mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
Merge pull request #28807 from Random-Liu/e2e-node-e2e-share-test
Automatic merge from submit-queue Node E2E: Make it possible to share test between e2e and node e2e This PR is part of the plan to improve node e2e test coverage. * Now to improve test coverage, we have to copy test from e2e to node e2e. * When adding a new test, we have to decide its destiny at the very beginning - whether it is a node e2e or e2e. This PR makes it possible to share test between e2e and node e2e. By leveraging the mechanism of ginkgo, as long as we can import the test package in the test suite, the corresponding `Describe` will be run to initialize the global variable `_`, and the test will be inserted into the test suite. (See https://github.com/onsi/composition-ginkgo-example) In the future, we just need to use the framework to write the test, and put the test into `test/e2e/node`, then it will be automatically shared by the 2 test suites. This PR: 1) Refactored the framework to make it automatically differentiate e2e and node e2e (Mainly refactored the `PodClient` and the apiserver client initialization). 2) Created a new directory `test/e2e/node` and make it shared by e2e and node e2e. 3) Moved `container_probe.go` into `test/e2e/node` to verify the change. @kubernetes/sig-node []()
This commit is contained in:
commit
af0835c0f4
@ -11,7 +11,6 @@ allow-privileged
|
||||
api-burst
|
||||
api-prefix
|
||||
api-rate
|
||||
api-server-address
|
||||
api-server-port
|
||||
api-servers
|
||||
api-token
|
||||
|
@ -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)
|
26
test/e2e/common/util.go
Normal file
26
test/e2e/common/util.go
Normal 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
|
@ -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"
|
||||
})
|
||||
|
||||
|
@ -34,6 +34,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"
|
||||
)
|
||||
|
||||
@ -137,6 +138,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) {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -103,6 +103,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.
|
||||
@ -118,7 +119,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.")
|
||||
|
@ -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) {
|
||||
|
@ -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"
|
||||
})
|
||||
|
||||
|
@ -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())
|
||||
}
|
||||
})
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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))
|
||||
})
|
||||
})
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user