Add tests for alias annotation

This commit is contained in:
Manuel de Brito Fontes 2017-11-09 23:00:38 -03:00
parent d4fd127a1f
commit 4c1c707e9c
10 changed files with 479 additions and 57 deletions

View file

@ -1016,8 +1016,7 @@ func (n *NGINXController) createServers(data []*extensions.Ingress,
} }
if !found { if !found {
glog.Warningf("ingress %v/%v for host %v contains a TLS section but none of the host match", // does not contains a TLS section but none of the host match
ing.Namespace, ing.Name, host)
continue continue
} }

View file

@ -0,0 +1,150 @@
/*
Copyright 2017 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 annotations
import (
"fmt"
"net/http"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/parnurzeal/gorequest"
v1beta1 "k8s.io/api/extensions/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/ingress-nginx/test/e2e/framework"
)
var _ = framework.IngressNginxDescribe("Annotations - Alias", func() {
f := framework.NewDefaultFramework("alias")
BeforeEach(func() {
err := f.NewEchoDeployment()
Expect(err).NotTo(HaveOccurred())
})
AfterEach(func() {
})
It("should return status code 200 for host 'foo' and 404 for 'bar'", func() {
host := "foo"
ing, err := f.EnsureIngress(&v1beta1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: host,
Namespace: f.Namespace.Name,
},
Spec: v1beta1.IngressSpec{
Rules: []v1beta1.IngressRule{
{
Host: host,
IngressRuleValue: v1beta1.IngressRuleValue{
HTTP: &v1beta1.HTTPIngressRuleValue{
Paths: []v1beta1.HTTPIngressPath{
{
Path: "/",
Backend: v1beta1.IngressBackend{
ServiceName: "http-svc",
ServicePort: intstr.FromInt(80),
},
},
},
},
},
},
},
},
})
Expect(err).NotTo(HaveOccurred())
Expect(ing).NotTo(BeNil())
err = f.WaitForNginxServer(host)
Expect(err).NotTo(HaveOccurred())
resp, body, errs := gorequest.New().
Get(f.NginxHTTPURL).
Set("Host", host).
End()
Expect(len(errs)).Should(BeNumerically("==", 0))
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
Expect(body).Should(ContainSubstring(fmt.Sprintf("host=%v", host)))
resp, body, errs = gorequest.New().
Get(f.NginxHTTPURL).
Set("Host", "bar").
End()
Expect(len(errs)).Should(BeNumerically("==", 0))
Expect(resp.StatusCode).Should(Equal(http.StatusNotFound))
Expect(body).Should(ContainSubstring("default backend - 404"))
})
It("should return status code 200 for host 'foo' and 'bar'", func() {
host := "bar"
ing, err := f.EnsureIngress(&v1beta1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: host,
Namespace: f.Namespace.Name,
Annotations: map[string]string{
"nginx.ingress.kubernetes.io/server-alias": host,
},
},
Spec: v1beta1.IngressSpec{
Rules: []v1beta1.IngressRule{
{
Host: "foo",
IngressRuleValue: v1beta1.IngressRuleValue{
HTTP: &v1beta1.HTTPIngressRuleValue{
Paths: []v1beta1.HTTPIngressPath{
{
Path: "/",
Backend: v1beta1.IngressBackend{
ServiceName: "http-svc",
ServicePort: intstr.FromInt(80),
},
},
},
},
},
},
},
},
})
Expect(err).NotTo(HaveOccurred())
Expect(ing).NotTo(BeNil())
err = f.WaitForNginxServer(host)
Expect(err).NotTo(HaveOccurred())
hosts := []string{"foo", "bar"}
for _, host := range hosts {
resp, body, errs := gorequest.New().
Get(f.NginxHTTPURL).
Set("Host", host).
End()
Expect(len(errs)).Should(BeNumerically("==", 0))
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
Expect(body).Should(ContainSubstring(fmt.Sprintf("host=%v", host)))
}
})
})

View file

@ -0,0 +1,15 @@
package annotations
// Tests:
// No auth
// Basic
// 401
// Realm name
// Auth ok
// Auth error
// Digest
// 401
// Realm name
// Auth ok
// Auth error
// Check return 403 if there's an error retrieving the secret

View file

@ -39,14 +39,6 @@ var _ = framework.IngressNginxDescribe("Default backend", func() {
}) })
It("should return 404 sending requests when only a default backend is running", func() { It("should return 404 sending requests when only a default backend is running", func() {
httpURL, err := f.GetNginxURL(framework.HTTP)
Expect(err).NotTo(HaveOccurred())
httpsURL, err := f.GetNginxURL(framework.HTTPS)
Expect(err).NotTo(HaveOccurred())
request := gorequest.New()
testCases := []struct { testCases := []struct {
Name string Name string
Host string Host string
@ -55,38 +47,39 @@ var _ = framework.IngressNginxDescribe("Default backend", func() {
Path string Path string
Status int Status int
}{ }{
{"basic HTTP GET request without host to path / should return 404", "", framework.HTTP, "GET", "/", 404}, {"basic HTTP GET request without host to path / should return 404", "", framework.HTTP, "GET", "/", http.StatusNotFound},
{"basic HTTP GET request without host to path /demo should return 404", "", framework.HTTP, "GET", "/demo", 404}, {"basic HTTP GET request without host to path /demo should return 404", "", framework.HTTP, "GET", "/demo", http.StatusNotFound},
{"basic HTTPS GET request without host to path / should return 404", "", framework.HTTPS, "GET", "/", 404}, {"basic HTTPS GET request without host to path / should return 404", "", framework.HTTPS, "GET", "/", http.StatusNotFound},
{"basic HTTPS GET request without host to path /demo should return 404", "", framework.HTTPS, "GET", "/demo", 404}, {"basic HTTPS GET request without host to path /demo should return 404", "", framework.HTTPS, "GET", "/demo", http.StatusNotFound},
{"basic HTTP POST request without host to path / should return 404", "", framework.HTTP, "POST", "/", 404}, {"basic HTTP POST request without host to path / should return 404", "", framework.HTTP, "POST", "/", http.StatusNotFound},
{"basic HTTP POST request without host to path /demo should return 404", "", framework.HTTP, "POST", "/demo", 404}, {"basic HTTP POST request without host to path /demo should return 404", "", framework.HTTP, "POST", "/demo", http.StatusNotFound},
{"basic HTTPS POST request without host to path / should return 404", "", framework.HTTPS, "POST", "/", 404}, {"basic HTTPS POST request without host to path / should return 404", "", framework.HTTPS, "POST", "/", http.StatusNotFound},
{"basic HTTPS POST request without host to path /demo should return 404", "", framework.HTTPS, "POST", "/demo", 404}, {"basic HTTPS POST request without host to path /demo should return 404", "", framework.HTTPS, "POST", "/demo", http.StatusNotFound},
{"basic HTTP GET request to host foo.bar.com and path / should return 404", " foo.bar.com", framework.HTTP, "GET", "/", 404}, {"basic HTTP GET request to host foo.bar.com and path / should return 404", " foo.bar.com", framework.HTTP, "GET", "/", http.StatusNotFound},
{"basic HTTP GET request to host foo.bar.com and path /demo should return 404", " foo.bar.com", framework.HTTP, "GET", "/demo", 404}, {"basic HTTP GET request to host foo.bar.com and path /demo should return 404", " foo.bar.com", framework.HTTP, "GET", "/demo", http.StatusNotFound},
{"basic HTTPS GET request to host foo.bar.com and path / should return 404", " foo.bar.com", framework.HTTPS, "GET", "/", 404}, {"basic HTTPS GET request to host foo.bar.com and path / should return 404", " foo.bar.com", framework.HTTPS, "GET", "/", http.StatusNotFound},
{"basic HTTPS GET request to host foo.bar.com and path /demo should return 404", " foo.bar.com", framework.HTTPS, "GET", "/demo", 404}, {"basic HTTPS GET request to host foo.bar.com and path /demo should return 404", " foo.bar.com", framework.HTTPS, "GET", "/demo", http.StatusNotFound},
{"basic HTTP POST request to host foo.bar.com and path / should return 404", " foo.bar.com", framework.HTTP, "POST", "/", 404}, {"basic HTTP POST request to host foo.bar.com and path / should return 404", " foo.bar.com", framework.HTTP, "POST", "/", http.StatusNotFound},
{"basic HTTP POST request to host foo.bar.com and path /demo should return 404", " foo.bar.com", framework.HTTP, "POST", "/demo", 404}, {"basic HTTP POST request to host foo.bar.com and path /demo should return 404", " foo.bar.com", framework.HTTP, "POST", "/demo", http.StatusNotFound},
{"basic HTTPS POST request to host foo.bar.com and path / should return 404", " foo.bar.com", framework.HTTPS, "POST", "/", 404}, {"basic HTTPS POST request to host foo.bar.com and path / should return 404", " foo.bar.com", framework.HTTPS, "POST", "/", http.StatusNotFound},
{"basic HTTPS POST request to host foo.bar.com and path /demo should return 404", " foo.bar.com", framework.HTTPS, "POST", "/demo", 404}, {"basic HTTPS POST request to host foo.bar.com and path /demo should return 404", " foo.bar.com", framework.HTTPS, "POST", "/demo", http.StatusNotFound},
} }
for _, test := range testCases { for _, test := range testCases {
By(test.Name) By(test.Name)
var errs []error
request := gorequest.New()
var cm *gorequest.SuperAgent var cm *gorequest.SuperAgent
switch test.Scheme { switch test.Scheme {
case framework.HTTP: case framework.HTTP:
cm = request.CustomMethod(test.Method, httpURL) cm = request.CustomMethod(test.Method, f.NginxHTTPURL)
break break
case framework.HTTPS: case framework.HTTPS:
cm = request.CustomMethod(test.Method, httpsURL) cm = request.CustomMethod(test.Method, f.NginxHTTPSURL)
// the default backend uses a self generated certificate // the default backend uses a self generated certificate
cm.Transport = &http.Transport{ cm.Transport = &http.Transport{
TLSClientConfig: &tls.Config{ TLSClientConfig: &tls.Config{

View file

@ -18,7 +18,6 @@ package defaultbackend
import ( import (
"crypto/tls" "crypto/tls"
"net/http"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
@ -37,36 +36,29 @@ var _ = framework.IngressNginxDescribe("Default backend - SSL", func() {
}) })
It("should return a self generated SSL certificate", func() { It("should return a self generated SSL certificate", func() {
httpsURL, err := f.GetNginxURL(framework.HTTPS)
Expect(err).NotTo(HaveOccurred())
request := gorequest.New()
By("checking SSL Certificate using the NGINX IP address") By("checking SSL Certificate using the NGINX IP address")
cm := request.Post(httpsURL) resp, _, errs := gorequest.New().
// the default backend uses a self generated certificate Post(f.NginxHTTPSURL).
cm.Transport = &http.Transport{ TLSClientConfig(&tls.Config{
TLSClientConfig: &tls.Config{ // the default backend uses a self generated certificate
InsecureSkipVerify: true, InsecureSkipVerify: true,
}, }).End()
}
resp, _, errs := cm.End()
Expect(len(errs)).Should(BeNumerically("==", 0)) Expect(len(errs)).Should(BeNumerically("==", 0))
Expect(len(resp.TLS.PeerCertificates)).Should(BeNumerically("==", 1)) Expect(len(resp.TLS.PeerCertificates)).Should(BeNumerically("==", 1))
for _, pc := range resp.TLS.PeerCertificates { for _, pc := range resp.TLS.PeerCertificates {
Expect(pc.Issuer.CommonName).Should(Equal("Kubernetes Ingress Controller Fake Certificate")) Expect(pc.Issuer.CommonName).Should(Equal("Kubernetes Ingress Controller Fake Certificate"))
} }
By("checking SSL Certificate using the NGINX catch all server") By("checking SSL Certificate using the NGINX catch all server")
cm = request.Post(httpsURL) resp, _, errs = gorequest.New().
// the default backend uses a self generated certificate Post(f.NginxHTTPSURL).
cm.Transport = &http.Transport{ TLSClientConfig(&tls.Config{
TLSClientConfig: &tls.Config{ // the default backend uses a self generated certificate
InsecureSkipVerify: true, InsecureSkipVerify: true,
}, }).
} Set("Host", "foo.bar.com").End()
cm.Set("Host", "foo.bar.com")
resp, _, errs = cm.End()
Expect(len(errs)).Should(BeNumerically("==", 0)) Expect(len(errs)).Should(BeNumerically("==", 0))
Expect(len(resp.TLS.PeerCertificates)).Should(BeNumerically("==", 1)) Expect(len(resp.TLS.PeerCertificates)).Should(BeNumerically("==", 1))
for _, pc := range resp.TLS.PeerCertificates { for _, pc := range resp.TLS.PeerCertificates {

View file

@ -26,6 +26,7 @@ import (
"k8s.io/apiserver/pkg/util/logs" "k8s.io/apiserver/pkg/util/logs"
_ "k8s.io/client-go/plugin/pkg/client/auth" _ "k8s.io/client-go/plugin/pkg/client/auth"
_ "k8s.io/ingress-nginx/test/e2e/annotations"
_ "k8s.io/ingress-nginx/test/e2e/defaultbackend" _ "k8s.io/ingress-nginx/test/e2e/defaultbackend"
"k8s.io/ingress-nginx/test/e2e/framework" "k8s.io/ingress-nginx/test/e2e/framework"
) )

118
test/e2e/framework/echo.go Normal file
View file

@ -0,0 +1,118 @@
/*
Copyright 2017 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 framework
import (
"fmt"
"time"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/util/intstr"
)
// NewEchoDeployment creates a new deployment of the echoserver image in a particular namespace
func (f *Framework) NewEchoDeployment() error {
deployment := &extensions.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "http-svc",
Namespace: f.Namespace.Name,
DeletionGracePeriodSeconds: NewInt64(5),
},
Spec: extensions.DeploymentSpec{
Replicas: NewInt32(1),
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"app": "http-svc",
},
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"app": "http-svc",
},
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "http-svc",
Image: "gcr.io/google_containers/echoserver:1.8",
Env: []corev1.EnvVar{},
Ports: []corev1.ContainerPort{
{
Name: "http",
ContainerPort: 8080,
},
},
},
},
},
},
},
}
d, err := f.EnsureDeployment(deployment)
if err != nil {
return err
}
if d == nil {
return fmt.Errorf("unexpected error creating deployement for echoserver")
}
err = f.WaitForPodsReady(10*time.Second, 1, metav1.ListOptions{
LabelSelector: fields.SelectorFromSet(fields.Set(d.Spec.Template.ObjectMeta.Labels)).String(),
})
if err != nil {
return errors.Wrap(err, "failed to wait for to become ready")
}
service := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "http-svc",
Namespace: f.Namespace.Name,
},
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
{
Name: "http",
Port: 80,
TargetPort: intstr.FromInt(8080),
Protocol: "TCP",
},
},
Selector: map[string]string{
"app": "http-svc",
},
},
}
s, err := f.EnsureService(service)
if err != nil {
return err
}
if s == nil {
return fmt.Errorf("unexpected error creating service for echoserver deployment")
}
return nil
}

View file

@ -17,10 +17,11 @@ import (
"fmt" "fmt"
"os/exec" "os/exec"
"strings" "strings"
"time"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
apiextcs "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" apiextcs "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
@ -31,6 +32,11 @@ const (
podName = "test-ingress-controller" podName = "test-ingress-controller"
) )
const (
MaxRetry = 200
NoRetry = 1
)
type RequestScheme string type RequestScheme string
// These are valid test request schemes. // These are valid test request schemes.
@ -54,9 +60,12 @@ type Framework struct {
// we install a Cleanup action before each test and clear it after. If we // we install a Cleanup action before each test and clear it after. If we
// should abort, the AfterSuite hook should run all Cleanup actions. // should abort, the AfterSuite hook should run all Cleanup actions.
cleanupHandle CleanupActionHandle cleanupHandle CleanupActionHandle
NginxHTTPURL string
NginxHTTPSURL string
} }
// NewFramework makes a new framework and sets up a BeforeEach/AfterEach for // NewDefaultFramework makes a new framework and sets up a BeforeEach/AfterEach for
// you (you can write additional before/after each functions). // you (you can write additional before/after each functions).
func NewDefaultFramework(baseName string) *Framework { func NewDefaultFramework(baseName string) *Framework {
f := &Framework{ f := &Framework{
@ -83,6 +92,14 @@ func (f *Framework) BeforeEach() {
By("Building a namespace api object") By("Building a namespace api object")
f.Namespace, err = CreateKubeNamespace(f.BaseName, f.KubeClientSet) f.Namespace, err = CreateKubeNamespace(f.BaseName, f.KubeClientSet)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
By("Building NGINX HTTP URL")
f.NginxHTTPURL, err = f.GetNginxURL(HTTP)
Expect(err).NotTo(HaveOccurred())
By("Building NGINX HTTPS URL")
f.NginxHTTPSURL, err = f.GetNginxURL(HTTPS)
Expect(err).NotTo(HaveOccurred())
} }
// AfterEach deletes the namespace, after reading its events. // AfterEach deletes the namespace, after reading its events.
@ -94,7 +111,7 @@ func (f *Framework) AfterEach() {
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
By("Waiting for test namespace to no longer exist") By("Waiting for test namespace to no longer exist")
err = WaitForKubeNamespaceNotExist(f.KubeClientSet, f.Namespace.Name) err = WaitForNoPodsInNamespace(f.KubeClientSet, f.Namespace.Name)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
} }
@ -115,7 +132,7 @@ func (f *Framework) GetNginxIP() (string, error) {
// GetNginxPort returns the number of TCP port where NGINX is running // GetNginxPort returns the number of TCP port where NGINX is running
func (f *Framework) GetNginxPort(name string) (int, error) { func (f *Framework) GetNginxPort(name string) (int, error) {
s, err := f.KubeClientSet.CoreV1().Services("ingress-nginx").Get("ingress-nginx", meta_v1.GetOptions{}) s, err := f.KubeClientSet.CoreV1().Services("ingress-nginx").Get("ingress-nginx", metav1.GetOptions{})
if err != nil { if err != nil {
return -1, err return -1, err
} }
@ -143,3 +160,8 @@ func (f *Framework) GetNginxURL(scheme RequestScheme) (string, error) {
return fmt.Sprintf("%v://%v:%v", scheme, ip, port), nil return fmt.Sprintf("%v://%v:%v", scheme, ip, port), nil
} }
func (f *Framework) WaitForNginxServer(name string) error {
time.Sleep(5 * time.Second)
return nil
}

95
test/e2e/framework/k8s.go Normal file
View file

@ -0,0 +1,95 @@
/*
Copyright 2017 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 framework
import (
"time"
api "k8s.io/api/core/v1"
core "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
)
func (f *Framework) EnsureSecret(secret *api.Secret) (*api.Secret, error) {
s, err := f.KubeClientSet.CoreV1().Secrets(secret.Namespace).Create(secret)
if err != nil {
if k8sErrors.IsAlreadyExists(err) {
return f.KubeClientSet.CoreV1().Secrets(secret.Namespace).Update(secret)
}
return nil, err
}
return s, nil
}
func (f *Framework) EnsureIngress(ingress *extensions.Ingress) (*extensions.Ingress, error) {
s, err := f.KubeClientSet.ExtensionsV1beta1().Ingresses(ingress.Namespace).Update(ingress)
if err != nil {
if k8sErrors.IsNotFound(err) {
return f.KubeClientSet.ExtensionsV1beta1().Ingresses(ingress.Namespace).Create(ingress)
}
return nil, err
}
return s, nil
}
func (f *Framework) EnsureService(service *core.Service) (*core.Service, error) {
s, err := f.KubeClientSet.CoreV1().Services(service.Namespace).Update(service)
if err != nil {
if k8sErrors.IsNotFound(err) {
return f.KubeClientSet.CoreV1().Services(service.Namespace).Create(service)
}
return nil, err
}
return s, nil
}
func (f *Framework) EnsureDeployment(deployment *extensions.Deployment) (*extensions.Deployment, error) {
d, err := f.KubeClientSet.Extensions().Deployments(deployment.Namespace).Update(deployment)
if err != nil {
if k8sErrors.IsNotFound(err) {
return f.KubeClientSet.Extensions().Deployments(deployment.Namespace).Create(deployment)
}
return nil, err
}
return d, nil
}
func (f *Framework) WaitForPodsReady(timeout time.Duration, expectedReplicas int, opts metav1.ListOptions) error {
return wait.Poll(time.Second, timeout, func() (bool, error) {
pl, err := f.KubeClientSet.Core().Pods(f.Namespace.Name).List(opts)
if err != nil {
return false, err
}
r := 0
for _, p := range pl.Items {
if p.Status.Phase != core.PodRunning {
continue
}
r++
}
if r == expectedReplicas {
return true, nil
}
return false, nil
})
}

View file

@ -120,7 +120,11 @@ func CreateKubeNamespace(baseName string, c kubernetes.Interface) (*v1.Namespace
} }
func DeleteKubeNamespace(c kubernetes.Interface, namespace string) error { func DeleteKubeNamespace(c kubernetes.Interface, namespace string) error {
return c.Core().Namespaces().Delete(namespace, nil) deletePolicy := metav1.DeletePropagationForeground
return c.Core().Namespaces().Delete(namespace, &metav1.DeleteOptions{
GracePeriodSeconds: NewInt64(0),
PropagationPolicy: &deletePolicy,
})
} }
func ExpectNoError(err error, explain ...interface{}) { func ExpectNoError(err error, explain ...interface{}) {
@ -131,7 +135,7 @@ func ExpectNoError(err error, explain ...interface{}) {
} }
func WaitForKubeNamespaceNotExist(c kubernetes.Interface, namespace string) error { func WaitForKubeNamespaceNotExist(c kubernetes.Interface, namespace string) error {
return wait.PollImmediate(Poll, time.Minute*2, namespaceNotExist(c, namespace)) return wait.PollImmediate(Poll, time.Minute*1, namespaceNotExist(c, namespace))
} }
func namespaceNotExist(c kubernetes.Interface, namespace string) wait.ConditionFunc { func namespaceNotExist(c kubernetes.Interface, namespace string) wait.ConditionFunc {
@ -147,7 +151,28 @@ func namespaceNotExist(c kubernetes.Interface, namespace string) wait.ConditionF
} }
} }
// Waits default amount of time (PodStartTimeout) for the specified pod to become running. func WaitForNoPodsInNamespace(c kubernetes.Interface, namespace string) error {
return wait.PollImmediate(Poll, time.Minute*2, noPodsInNamespace(c, namespace))
}
func noPodsInNamespace(c kubernetes.Interface, namespace string) wait.ConditionFunc {
return func() (bool, error) {
items, err := c.CoreV1().Pods(namespace).List(metav1.ListOptions{})
if apierrors.IsNotFound(err) {
return true, nil
}
if err != nil {
return false, err
}
if len(items.Items) == 0 {
return true, nil
}
return false, nil
}
}
// WaitForPodRunningInNamespace waits default amount of time (PodStartTimeout) for the specified pod to become running.
// Returns an error if timeout occurs first, or pod goes in to failed state. // Returns an error if timeout occurs first, or pod goes in to failed state.
func WaitForPodRunningInNamespace(c kubernetes.Interface, pod *v1.Pod) error { func WaitForPodRunningInNamespace(c kubernetes.Interface, pod *v1.Pod) error {
if pod.Status.Phase == v1.PodRunning { if pod.Status.Phase == v1.PodRunning {
@ -175,3 +200,15 @@ func podRunning(c kubernetes.Interface, podName, namespace string) wait.Conditio
return false, nil return false, nil
} }
} }
func NewInt32(val int32) *int32 {
p := new(int32)
*p = val
return p
}
func NewInt64(val int64) *int64 {
p := new(int64)
*p = val
return p
}