Make it possible to share test between e2e and node e2e,

and make container probing test shared to validate.
This commit is contained in:
Random-Liu 2016-07-07 22:56:46 -07:00
parent d168bbe3b8
commit e40e82bd5c
21 changed files with 156 additions and 154 deletions

View File

@ -11,7 +11,6 @@ allow-privileged
api-burst api-burst
api-prefix api-prefix
api-rate api-rate
api-server-address
api-server-port api-server-port
api-servers api-servers
api-token api-token

View File

@ -14,17 +14,15 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package e2e package common
import ( import (
"fmt" "fmt"
"time" "time"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/intstr" "k8s.io/kubernetes/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util/wait"
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
@ -33,36 +31,23 @@ import (
const ( const (
probTestContainerName = "test-webserver" probTestContainerName = "test-webserver"
probTestInitialDelaySeconds = 30 probTestInitialDelaySeconds = 15
) )
var _ = framework.KubeDescribe("Probing container", func() { var _ = framework.KubeDescribe("Probing container", func() {
f := framework.NewDefaultFramework("container-probe") f := framework.NewDefaultFramework("container-probe")
var podClient client.PodInterface var podClient *framework.PodClient
probe := webserverProbeBuilder{} probe := webserverProbeBuilder{}
BeforeEach(func() { 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() { 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)) p := podClient.Create(makePodSpec(probe.withInitialDelay().build(), nil))
framework.ExpectNoError(err) f.WaitForPodReady(p.Name)
Expect(wait.Poll(framework.Poll, 240*time.Second, func() (bool, error) {
p, err := podClient.Get(p.Name) 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)
framework.ExpectNoError(err) framework.ExpectNoError(err)
isReady, err := framework.PodRunningReady(p) isReady, err := framework.PodRunningReady(p)
framework.ExpectNoError(err) 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() { It("with readiness probe that fails should never be ready and never restart [Conformance]", func() {
p, err := podClient.Create(makePodSpec(probe.withFailing().build(), nil)) p := podClient.Create(makePodSpec(probe.withFailing().build(), nil))
framework.ExpectNoError(err) Consistently(func() (bool, error) {
err = wait.Poll(framework.Poll, 180*time.Second, func() (bool, error) {
p, err := podClient.Get(p.Name) p, err := podClient.Get(p.Name)
if err != nil { if err != nil {
return false, err return false, err
} }
return api.IsPodReady(p), nil return api.IsPodReady(p), nil
}) }, 1*time.Minute, 1*time.Second).ShouldNot(BeTrue(), "pod should not be ready")
if err != wait.ErrWaitTimeout {
framework.Failf("expecting wait timeout error but got: %v", err)
}
p, err = podClient.Get(p.Name) p, err := podClient.Get(p.Name)
framework.ExpectNoError(err) framework.ExpectNoError(err)
isReady, err := framework.PodRunningReady(p) isReady, err := framework.PodRunningReady(p)

26
test/e2e/common/util.go Normal file
View File

@ -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

View File

@ -81,7 +81,7 @@ var _ = framework.KubeDescribe("Downward API volume", func() {
podLogTimeout, framework.Poll).Should(ContainSubstring("key1=\"value1\"\n")) podLogTimeout, framework.Poll).Should(ContainSubstring("key1=\"value1\"\n"))
//modify labels //modify labels
f.UpdatePod(podName, func(pod *api.Pod) { f.PodClient().Update(podName, func(pod *api.Pod) {
pod.Labels["key3"] = "value3" pod.Labels["key3"] = "value3"
}) })
@ -116,7 +116,7 @@ var _ = framework.KubeDescribe("Downward API volume", func() {
podLogTimeout, framework.Poll).Should(ContainSubstring("builder=\"bar\"\n")) podLogTimeout, framework.Poll).Should(ContainSubstring("builder=\"bar\"\n"))
//modify annotations //modify annotations
f.UpdatePod(podName, func(pod *api.Pod) { f.PodClient().Update(podName, func(pod *api.Pod) {
pod.Annotations["builder"] = "foo" pod.Annotations["builder"] = "foo"
}) })

View File

@ -36,6 +36,7 @@ import (
gcecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" gcecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/gce"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/runtime" "k8s.io/kubernetes/pkg/util/runtime"
commontest "k8s.io/kubernetes/test/e2e/common"
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
) )
@ -146,6 +147,9 @@ var _ = ginkgo.SynchronizedBeforeSuite(func() []byte {
framework.LogContainersInPodsWithLabels(c, api.NamespaceSystem, framework.ImagePullerLabels, "nethealth") framework.LogContainersInPodsWithLabels(c, api.NamespaceSystem, framework.ImagePullerLabels, "nethealth")
} }
// Reference common test to make the import valid.
commontest.CurrentSuite = commontest.E2E
return nil return nil
}, func(data []byte) { }, func(data []byte) {

View File

@ -32,6 +32,7 @@ import (
apierrs "k8s.io/kubernetes/pkg/api/errors" 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_2"
"k8s.io/kubernetes/pkg/client/clientset_generated/release_1_3" "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_3"
"k8s.io/kubernetes/pkg/client/restclient"
client "k8s.io/kubernetes/pkg/client/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/labels"
@ -53,7 +54,6 @@ const (
type Framework struct { type Framework struct {
BaseName string BaseName string
ClientConfigGetter ClientConfigGetter
Client *client.Client Client *client.Client
Clientset_1_2 *release_1_2.Clientset Clientset_1_2 *release_1_2.Clientset
Clientset_1_3 *release_1_3.Clientset Clientset_1_3 *release_1_3.Clientset
@ -117,16 +117,11 @@ func NewDefaultFederatedFramework(baseName string) *Framework {
} }
func NewFramework(baseName string, options FrameworkOptions, client *client.Client) *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{ f := &Framework{
BaseName: baseName, BaseName: baseName,
AddonResourceConstraints: make(map[string]ResourceConstraint), AddonResourceConstraints: make(map[string]ResourceConstraint),
options: options, options: options,
Client: client, Client: client,
ClientConfigGetter: configGetter,
} }
BeforeEach(f.BeforeEach) BeforeEach(f.BeforeEach)
@ -142,10 +137,21 @@ func (f *Framework) BeforeEach() {
f.cleanupHandle = AddCleanupAction(f.AfterEach) f.cleanupHandle = AddCleanupAction(f.AfterEach)
if f.Client == nil { if f.Client == nil {
By("Creating a kubernetes client") By("Creating a kubernetes client")
config, err := f.ClientConfigGetter() 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()) Expect(err).NotTo(HaveOccurred())
config.QPS = f.options.ClientQPS config.QPS = f.options.ClientQPS
config.Burst = f.options.ClientBurst config.Burst = f.options.ClientBurst
}
if TestContext.KubeAPIContentType != "" { if TestContext.KubeAPIContentType != "" {
config.ContentType = TestContext.KubeAPIContentType config.ContentType = TestContext.KubeAPIContentType
} }

View File

@ -29,43 +29,46 @@ import (
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
) )
// TODO: Consolidate pod-specific framework functions here.
// Convenience method for getting a pod client interface in the framework's namespace. // Convenience method for getting a pod client interface in the framework's namespace.
func (f *Framework) PodClient() unversioned.PodInterface { func (f *Framework) PodClient() *PodClient {
return f.Client.Pods(f.Namespace.Name) 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. type PodClient struct {
// Returns the server's representation of the pod. f *Framework
func (f *Framework) CreatePod(pod *api.Pod) *api.Pod { unversioned.PodInterface
p := f.CreatePodAsync(pod)
ExpectNoError(f.WaitForPodRunning(p.Name))
return p
} }
// Create a new pod according to the framework specifications (don't wait for it to start). // Create creates a new pod according to the framework specifications (don't wait for it to start).
// Returns the server's representation of the pod. func (c *PodClient) Create(pod *api.Pod) *api.Pod {
func (f *Framework) CreatePodAsync(pod *api.Pod) *api.Pod { c.MungeSpec(pod)
f.MungePodSpec(pod) p, err := c.PodInterface.Create(pod)
p, err := f.PodClient().Create(pod)
ExpectNoError(err, "Error creating Pod") ExpectNoError(err, "Error creating Pod")
return p return p
} }
// Batch version of CreatePod. All pods are created before waiting. // CreateSync creates a new pod according to the framework specifications, and wait for it to start.
// Returns a slice, in the same order as pods, containing the server's representations of the pods. func (c *PodClient) CreateSync(pod *api.Pod) *api.Pod {
func (f *Framework) CreatePods(pods []*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)) ps := make([]*api.Pod, len(pods))
for i, pod := range pods { for i, pod := range pods {
ps[i] = f.CreatePodAsync(pod) ps[i] = c.Create(pod)
} }
var wg sync.WaitGroup var wg sync.WaitGroup
for _, pod := range ps { for _, pod := range ps {
wg.Add(1) wg.Add(1)
podName := pod.Name podName := pod.Name
go func() { go func() {
ExpectNoError(f.WaitForPodRunning(podName)) ExpectNoError(c.f.WaitForPodRunning(podName))
wg.Done() wg.Done()
}() }()
} }
@ -73,26 +76,27 @@ func (f *Framework) CreatePods(pods []*api.Pod) []*api.Pod {
return ps return ps
} }
// Apply test-suite specific transformations to the pod spec. // MungeSpec apply test-suite specific transformations to the pod spec.
// TODO: figure out a nicer, more generic way to tie this to framework instances. // TODO: Refactor the framework to always use PodClient so that we can completely hide the munge logic
func (f *Framework) MungePodSpec(pod *api.Pod) { // in the PodClient.
func (c *PodClient) MungeSpec(pod *api.Pod) {
if TestContext.NodeName != "" { if TestContext.NodeName != "" {
Expect(pod.Spec.NodeName).To(Or(BeZero(), Equal(TestContext.NodeName)), "Test misconfigured") Expect(pod.Spec.NodeName).To(Or(BeZero(), Equal(TestContext.NodeName)), "Test misconfigured")
pod.Spec.NodeName = TestContext.NodeName 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 // there is any other errors. name is the pod name, updateFn is the function updating the
// pod object. // 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) { 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 { if err != nil {
return false, fmt.Errorf("failed to get pod %q: %v", name, err) return false, fmt.Errorf("failed to get pod %q: %v", name, err)
} }
updateFn(pod) updateFn(pod)
_, err = f.PodClient().Update(pod) _, err = c.PodInterface.Update(pod)
if err == nil { if err == nil {
Logf("Successfully updated pod %q", name) Logf("Successfully updated pod %q", name)
return true, nil 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) return false, fmt.Errorf("failed to update pod %q: %v", name, err)
})) }))
} }
// TODO(random-liu): Move pod wait function into this file

View File

@ -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.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.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.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. // 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.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.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.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.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.") flag.StringVar(&TestContext.KubectlPath, "kubectl-path", "kubectl", "The kubectl binary to use. For development, you might use 'cluster/kubectl.sh' here.")

View File

@ -24,7 +24,6 @@ import (
api "k8s.io/kubernetes/pkg/api" api "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/apimachinery/registered"
client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
) )
@ -84,29 +83,12 @@ func (config *KubeletManagedHostConfig) setup() {
func (config *KubeletManagedHostConfig) createPodWithoutHostNetwork() { func (config *KubeletManagedHostConfig) createPodWithoutHostNetwork() {
podSpec := config.createPodSpec(kubeletEtcHostsPodName) podSpec := config.createPodSpec(kubeletEtcHostsPodName)
config.pod = config.createPod(podSpec) config.pod = config.f.PodClient().CreateSync(podSpec)
} }
func (config *KubeletManagedHostConfig) createPodWithHostNetwork() { func (config *KubeletManagedHostConfig) createPodWithHostNetwork() {
podSpec := config.createPodSpecWithHostNetwork(kubeletEtcHostsHostNetworkPodName) podSpec := config.createPodSpecWithHostNetwork(kubeletEtcHostsHostNetworkPodName)
config.hostNetworkPod = config.createPod(podSpec) config.hostNetworkPod = config.f.PodClient().CreateSync(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)
} }
func assertEtcHostsIsKubeletManaged(etcHostsContent string) { func assertEtcHostsIsKubeletManaged(etcHostsContent string) {

View File

@ -462,7 +462,7 @@ var _ = framework.KubeDescribe("Pods", func() {
Expect(len(pods.Items)).To(Equal(1)) Expect(len(pods.Items)).To(Equal(1))
By("updating the pod") 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()) value = strconv.Itoa(time.Now().Nanosecond())
pod.Labels["time"] = value pod.Labels["time"] = value
}) })
@ -530,7 +530,7 @@ var _ = framework.KubeDescribe("Pods", func() {
Expect(len(pods.Items)).To(Equal(1)) Expect(len(pods.Items)).To(Equal(1))
By("updating the pod") By("updating the pod")
f.UpdatePod(name, func(pod *api.Pod) { f.PodClient().Update(name, func(pod *api.Pod) {
newDeadline := int64(5) newDeadline := int64(5)
pod.Spec.ActiveDeadlineSeconds = &newDeadline pod.Spec.ActiveDeadlineSeconds = &newDeadline
}) })
@ -1309,7 +1309,7 @@ var _ = framework.KubeDescribe("Pods", func() {
delay1, delay2 := startPodAndGetBackOffs(f, pod, podName, containerName, buildBackOffDuration) delay1, delay2 := startPodAndGetBackOffs(f, pod, podName, containerName, buildBackOffDuration)
By("updating the image") 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" pod.Spec.Containers[0].Image = "gcr.io/google_containers/nginx-slim:0.7"
}) })

View File

@ -26,7 +26,7 @@ import (
) )
var _ = framework.KubeDescribe("Kubelet Cgroup Manager", func() { var _ = framework.KubeDescribe("Kubelet Cgroup Manager", func() {
f := NewDefaultFramework("kubelet-cgroup-manager") f := framework.NewDefaultFramework("kubelet-cgroup-manager")
Describe("QOS containers", func() { Describe("QOS containers", func() {
Context("On enabling QOS cgroup hierarchy", func() { Context("On enabling QOS cgroup hierarchy", func() {
It("Top level QoS containers should have been created", func() { It("Top level QoS containers should have been created", func() {
@ -36,7 +36,6 @@ var _ = framework.KubeDescribe("Kubelet Cgroup Manager", func() {
pod := &api.Pod{ pod := &api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: podName, Name: podName,
Namespace: f.Namespace.Name,
}, },
Spec: api.PodSpec{ Spec: api.PodSpec{
// Don't restart the Pod since it is expected to exit // 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.PodClient()
podClient := f.Client.Pods(f.Namespace.Name) podClient.Create(pod)
_, err := podClient.Create(pod) err := framework.WaitForPodSuccessInNamespace(f.Client, podName, contName, f.Namespace.Name)
Expect(err).NotTo(HaveOccurred())
err = framework.WaitForPodSuccessInNamespace(f.Client, podName, contName, f.Namespace.Name)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
} }
}) })

View File

@ -30,7 +30,7 @@ import (
var _ = framework.KubeDescribe("ConfigMap", func() { var _ = framework.KubeDescribe("ConfigMap", func() {
f := NewDefaultFramework("configmap") f := framework.NewDefaultFramework("configmap")
It("should be consumable from pods in volumpe [Conformance]", func() { It("should be consumable from pods in volumpe [Conformance]", func() {
doConfigMapE2EWithoutMappings(f, 0, 0) doConfigMapE2EWithoutMappings(f, 0, 0)
@ -122,7 +122,7 @@ var _ = framework.KubeDescribe("ConfigMap", func() {
} }
By("Creating the pod") By("Creating the pod")
f.CreatePod(pod) f.PodClient().CreateSync(pod)
pollLogs := func() (string, error) { pollLogs := func() (string, error) {
return framework.GetPodLogs(f.Client, f.Namespace.Name, pod.Name, containerName) 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{ framework.TestContainerOutput("consume configMaps", f.Client, pod, 0, []string{
"CONFIG_DATA_1=value-1", "CONFIG_DATA_1=value-1",
@ -260,7 +261,7 @@ func doConfigMapE2EWithoutMappings(f *framework.Framework, uid, fsGroup int64) {
pod.Spec.SecurityContext.FSGroup = &fsGroup pod.Spec.SecurityContext.FSGroup = &fsGroup
} }
f.MungePodSpec(pod) f.PodClient().MungeSpec(pod)
framework.TestContainerOutput("consume configMaps", f.Client, pod, 0, []string{ framework.TestContainerOutput("consume configMaps", f.Client, pod, 0, []string{
"content of file \"/etc/configmap-volume/data-1\": value-1", "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 pod.Spec.SecurityContext.FSGroup = &fsGroup
} }
f.MungePodSpec(pod) f.PodClient().MungeSpec(pod)
framework.TestContainerOutput("consume configMaps", f.Client, pod, 0, []string{ framework.TestContainerOutput("consume configMaps", f.Client, pod, 0, []string{
"content of file \"/etc/configmap-volume/path/to/data-2\": value-2", "content of file \"/etc/configmap-volume/path/to/data-2\": value-2",

View File

@ -28,12 +28,12 @@ import (
// One pod one container // One pod one container
// TODO: This should be migrated to the e2e framework. // TODO: This should be migrated to the e2e framework.
type ConformanceContainer struct { type ConformanceContainer struct {
Framework *framework.Framework
Container api.Container Container api.Container
RestartPolicy api.RestartPolicy RestartPolicy api.RestartPolicy
Volumes []api.Volume Volumes []api.Volume
ImagePullSecrets []string ImagePullSecrets []string
PodClient *framework.PodClient
podName string podName string
PodSecurityContext *api.PodSecurityContext PodSecurityContext *api.PodSecurityContext
} }
@ -58,15 +58,15 @@ func (cc *ConformanceContainer) Create() {
ImagePullSecrets: imagePullSecrets, ImagePullSecrets: imagePullSecrets,
}, },
} }
cc.Framework.CreatePodAsync(pod) cc.PodClient.Create(pod)
} }
func (cc *ConformanceContainer) Delete() error { 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) { func (cc *ConformanceContainer) IsReady() (bool, error) {
pod, err := cc.Framework.PodClient().Get(cc.podName) pod, err := cc.PodClient.Get(cc.podName)
if err != nil { if err != nil {
return false, err return false, err
} }
@ -74,7 +74,7 @@ func (cc *ConformanceContainer) IsReady() (bool, error) {
} }
func (cc *ConformanceContainer) GetPhase() (api.PodPhase, 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 { if err != nil {
return api.PodUnknown, err return api.PodUnknown, err
} }
@ -82,7 +82,7 @@ func (cc *ConformanceContainer) GetPhase() (api.PodPhase, error) {
} }
func (cc *ConformanceContainer) GetStatus() (api.ContainerStatus, 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 { if err != nil {
return api.ContainerStatus{}, err return api.ContainerStatus{}, err
} }
@ -94,7 +94,7 @@ func (cc *ConformanceContainer) GetStatus() (api.ContainerStatus, error) {
} }
func (cc *ConformanceContainer) Present() (bool, error) { func (cc *ConformanceContainer) Present() (bool, error) {
_, err := cc.Framework.PodClient().Get(cc.podName) _, err := cc.PodClient.Get(cc.podName)
if err == nil { if err == nil {
return true, nil return true, nil
} }

View File

@ -29,14 +29,20 @@ import (
) )
var _ = framework.KubeDescribe("Kubelet Container Manager", func() { 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() { Describe("oom score adjusting", func() {
Context("when scheduling a busybox command that always fails in a pod", func() { Context("when scheduling a busybox command that always fails in a pod", func() {
var podName string var podName string
BeforeEach(func() { BeforeEach(func() {
podName = "bin-false" + string(util.NewUUID()) podName = "bin-false" + string(util.NewUUID())
f.CreatePodAsync(&api.Pod{ podClient.Create(&api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: podName, Name: podName,
}, },
@ -56,7 +62,7 @@ var _ = framework.KubeDescribe("Kubelet Container Manager", func() {
It("should have an error terminated reason", func() { It("should have an error terminated reason", func() {
Eventually(func() error { Eventually(func() error {
podData, err := f.PodClient().Get(podName) podData, err := podClient.Get(podName)
if err != nil { if err != nil {
return err return err
} }
@ -75,7 +81,7 @@ var _ = framework.KubeDescribe("Kubelet Container Manager", func() {
}) })
It("should be possible to delete", 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)) Expect(err).To(BeNil(), fmt.Sprintf("Error deleting Pod %v", err))
}) })
}) })

View File

@ -30,7 +30,7 @@ import (
// Ported from test/e2e/downard_api_test.go // Ported from test/e2e/downard_api_test.go
var _ = framework.KubeDescribe("Downward API", func() { 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() { It("should provide pod name and namespace as env vars [Conformance]", func() {
podName := "downward-api-" + string(util.NewUUID()) podName := "downward-api-" + string(util.NewUUID())
env := []api.EnvVar{ env := []api.EnvVar{
@ -158,7 +158,8 @@ func testDownwardAPI(f *framework.Framework, podName string, env []api.EnvVar, e
RestartPolicy: api.RestartPolicyNever, 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) f.TestContainerOutputRegexp("downward api env vars", pod, 0, expectations)
} }

View File

@ -31,6 +31,7 @@ import (
"testing" "testing"
"time" "time"
commontest "k8s.io/kubernetes/test/e2e/common"
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
"github.com/golang/glog" "github.com/golang/glog"
@ -104,6 +105,9 @@ var _ = BeforeSuite(func() {
} else { } else {
glog.Infof("Running tests without starting services.") 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 // Tear down the kubelet on the node

View File

@ -38,11 +38,15 @@ import (
) )
var _ = framework.KubeDescribe("Kubelet", func() { 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() { Context("when scheduling a busybox command in a pod", func() {
podName := "busybox-scheduling-" + string(util.NewUUID()) podName := "busybox-scheduling-" + string(util.NewUUID())
It("it should print the output to logs", func() { It("it should print the output to logs", func() {
f.CreatePod(&api.Pod{ podClient.CreateSync(&api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: podName, Name: podName,
}, },
@ -60,7 +64,7 @@ var _ = framework.KubeDescribe("Kubelet", func() {
}) })
Eventually(func() string { Eventually(func() string {
sinceTime := apiUnversioned.NewTime(time.Now().Add(time.Duration(-1 * time.Hour))) 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 { if err != nil {
return "" return ""
} }
@ -76,7 +80,7 @@ var _ = framework.KubeDescribe("Kubelet", func() {
podName := "busybox-readonly-fs" + string(util.NewUUID()) podName := "busybox-readonly-fs" + string(util.NewUUID())
It("it should not write to root filesystem", func() { It("it should not write to root filesystem", func() {
isReadOnly := true isReadOnly := true
f.CreatePod(&api.Pod{ podClient.CreateSync(&api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: podName, Name: podName,
}, },
@ -96,7 +100,7 @@ var _ = framework.KubeDescribe("Kubelet", func() {
}, },
}) })
Eventually(func() string { Eventually(func() string {
rc, err := f.PodClient().GetLogs(podName, &api.PodLogOptions{}).Stream() rc, err := podClient.GetLogs(podName, &api.PodLogOptions{}).Stream()
if err != nil { if err != nil {
return "" return ""
} }
@ -112,7 +116,7 @@ var _ = framework.KubeDescribe("Kubelet", func() {
It("it should report resource usage through the stats api", func() { It("it should report resource usage through the stats api", func() {
podNamePrefix := "stats-busybox-" + string(util.NewUUID()) podNamePrefix := "stats-busybox-" + string(util.NewUUID())
volumeNamePrefix := "test-empty-dir" volumeNamePrefix := "test-empty-dir"
podNames, volumes := createSummaryTestPods(f, podNamePrefix, 2, volumeNamePrefix) podNames, volumes := createSummaryTestPods(f.PodClient(), podNamePrefix, 2, volumeNamePrefix)
By("Returning stats summary") By("Returning stats summary")
summary := stats.Summary{} summary := stats.Summary{}
Eventually(func() error { Eventually(func() error {
@ -152,7 +156,7 @@ const (
containerSuffix = "-c" 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() podNames := sets.NewString()
volumes := sets.NewString(volumeNamePrefix) volumes := sets.NewString(volumeNamePrefix)
for i := 0; i < count; i++ { 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 return podNames, volumes
} }

View File

@ -35,7 +35,7 @@ import (
) )
var _ = framework.KubeDescribe("MirrorPod", func() { var _ = framework.KubeDescribe("MirrorPod", func() {
f := NewDefaultFramework("mirror-pod") f := framework.NewDefaultFramework("mirror-pod")
Context("when create a mirror pod ", func() { Context("when create a mirror pod ", func() {
var staticPodName, mirrorPodName string var staticPodName, mirrorPodName string
BeforeEach(func() { BeforeEach(func() {

View File

@ -54,11 +54,13 @@ type PrivilegedPodTestConfig struct {
privilegedPod *api.Pod privilegedPod *api.Pod
} }
// TODO(random-liu): Change the test to use framework and framework pod client.
var _ = Describe("PrivilegedPod", func() { var _ = Describe("PrivilegedPod", func() {
var c *client.Client var c *client.Client
restClientConfig := &restclient.Config{Host: *apiServerAddress} var restClientConfig *restclient.Config
BeforeEach(func() { BeforeEach(func() {
// Setup the apiserver client // Setup the apiserver client
restClientConfig = &restclient.Config{Host: framework.TestContext.Host}
c = client.NewOrDie(restClientConfig) c = client.NewOrDie(restClientConfig)
}) })
It("should test privileged pod", func() { It("should test privileged pod", func() {

View File

@ -37,7 +37,7 @@ const (
) )
var _ = framework.KubeDescribe("Container Runtime Conformance Test", func() { var _ = framework.KubeDescribe("Container Runtime Conformance Test", func() {
f := NewDefaultFramework("runtime-conformance") f := framework.NewDefaultFramework("runtime-conformance")
Describe("container runtime conformance blackbox test", func() { Describe("container runtime conformance blackbox test", func() {
Context("when starting a container that exits", func() { Context("when starting a container that exits", func() {
@ -91,7 +91,7 @@ while true; do sleep 1; done
testContainer.Name = testCase.Name testContainer.Name = testCase.Name
testContainer.Command = []string{"sh", "-c", tmpCmd} testContainer.Command = []string{"sh", "-c", tmpCmd}
terminateContainer := ConformanceContainer{ terminateContainer := ConformanceContainer{
Framework: f, PodClient: f.PodClient(),
Container: testContainer, Container: testContainer,
RestartPolicy: testCase.RestartPolicy, RestartPolicy: testCase.RestartPolicy,
Volumes: testVolumes, Volumes: testVolumes,
@ -134,7 +134,7 @@ while true; do sleep 1; done
terminationMessagePath := "/dev/termination-log" terminationMessagePath := "/dev/termination-log"
priv := true priv := true
c := ConformanceContainer{ c := ConformanceContainer{
Framework: f, PodClient: f.PodClient(),
Container: api.Container{ Container: api.Container{
Image: ImageRegistry[busyBoxImage], Image: ImageRegistry[busyBoxImage],
Name: name, Name: name,
@ -235,7 +235,7 @@ while true; do sleep 1; done
name := "image-pull-test" name := "image-pull-test"
command := []string{"/bin/sh", "-c", "while true; do sleep 1; done"} command := []string{"/bin/sh", "-c", "while true; do sleep 1; done"}
container := ConformanceContainer{ container := ConformanceContainer{
Framework: f, PodClient: f.PodClient(),
Container: api.Container{ Container: api.Container{
Name: name, Name: name,
Image: testCase.image, Image: testCase.image,

View File

@ -18,27 +18,11 @@ package e2e_node
import ( import (
"flag" "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 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 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 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 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") 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)
}