Remove hard-coded names from e2e test and use local docker dependencies (#4502)

This commit is contained in:
Manuel Alejandro de Brito Fontes 2019-09-01 14:16:52 -04:00 committed by GitHub
parent c7d2444cf4
commit c85450c1e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
68 changed files with 894 additions and 293 deletions

View file

@ -27,6 +27,15 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
)
// EchoService name of the deployment for the echo app
const EchoService = "echo"
// SlowEchoService name of the deployment for the echo app
const SlowEchoService = "slow-echo"
// HTTPBinService name of the deployment for the httpbin app
const HTTPBinService = "httpbin"
// NewEchoDeployment creates a new single replica deployment of the echoserver image in a particular namespace
func (f *Framework) NewEchoDeployment() {
f.NewEchoDeploymentWithReplicas(1)
@ -34,32 +43,266 @@ func (f *Framework) NewEchoDeployment() {
// NewEchoDeploymentWithReplicas creates a new deployment of the echoserver image in a particular namespace. Number of
// replicas is configurable
func (f *Framework) NewEchoDeploymentWithReplicas(replicas int32) {
f.NewEchoDeploymentWithNameAndReplicas("http-svc", replicas)
func (f *Framework) NewEchoDeploymentWithReplicas(replicas int) {
f.NewEchoDeploymentWithNameAndReplicas(EchoService, replicas)
}
// NewEchoDeploymentWithNameAndReplicas creates a new deployment of the echoserver image in a particular namespace. Number of
// replicas is configurable and
// name is configurable
func (f *Framework) NewEchoDeploymentWithNameAndReplicas(name string, replicas int32) {
f.NewDeployment(name, "gcr.io/kubernetes-e2e-test-images/echoserver:2.2", 8080, replicas)
func (f *Framework) NewEchoDeploymentWithNameAndReplicas(name string, replicas int) {
data := map[string]string{}
data["nginx.conf"] = `#
env HOSTNAME;
env NODE_NAME;
env POD_NAME;
env POD_NAMESPACE;
env POD_IP;
daemon off;
events {
worker_connections 1024;
}
http {
default_type 'text/plain';
client_max_body_size 0;
init_by_lua_block {
local template = require "resty.template"
tmpl = template.compile([[
Hostname: {*os.getenv("HOSTNAME") or "N/A"*}
Pod Information:
{% if os.getenv("POD_NAME") then %}
node name: {*os.getenv("NODE_NAME") or "N/A"*}
pod name: {*os.getenv("POD_NAME") or "N/A"*}
pod namespace: {*os.getenv("POD_NAMESPACE") or "N/A"*}
pod IP: {*os.getenv("POD_IP") or "N/A"*}
{% else %}
-no pod information available-
{% end %}
Server values:
server_version=nginx: {*ngx.var.nginx_version*} - lua: {*ngx.config.ngx_lua_version*}
Request Information:
client_address={*ngx.var.remote_addr*}
method={*ngx.req.get_method()*}
real path={*ngx.var.request_uri*}
query={*ngx.var.query_string or ""*}
request_version={*ngx.req.http_version()*}
request_scheme={*ngx.var.scheme*}
request_uri={*ngx.var.scheme.."://"..ngx.var.host..":"..ngx.var.server_port..ngx.var.request_uri*}
Request Headers:
{% for i, key in ipairs(keys) do %}
{% local val = headers[key] %}
{% if type(val) == "table" then %}
{% for i = 1,#val do %}
{*key*}={*val[i]*}
{% end %}
{% else %}
{*key*}={*val*}
{% end %}
{% end %}
Request Body:
{*ngx.var.request_body or " -no body in request-"*}
]])
}
server {
listen 80 default_server reuseport;
server_name _;
keepalive_timeout 620s;
location / {
lua_need_request_body on;
content_by_lua_block {
ngx.header["Server"] = "echoserver"
local headers = ngx.req.get_headers()
local keys = {}
for key, val in pairs(headers) do
table.insert(keys, key)
end
table.sort(keys)
ngx.say(tmpl({os=os, ngx=ngx, keys=keys, headers=headers}))
}
}
}
}
`
_, err := f.KubeClientSet.CoreV1().ConfigMaps(f.Namespace).Create(&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: f.Namespace,
},
Data: data,
})
Expect(err).NotTo(HaveOccurred(), "failed to create a deployment")
deployment := newDeployment(name, f.Namespace, "openresty/openresty:1.15.8.2-alpine", 80, int32(replicas),
[]string{
"/bin/sh",
"-c",
"apk add -U perl curl && opm get bungle/lua-resty-template && openresty",
},
[]corev1.VolumeMount{
{
Name: name,
MountPath: "/usr/local/openresty/nginx/conf/nginx.conf",
SubPath: "nginx.conf",
ReadOnly: true,
},
},
[]corev1.Volume{
{
Name: name,
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: name,
},
},
},
},
},
)
d, err := f.EnsureDeployment(deployment)
Expect(err).NotTo(HaveOccurred(), "failed to create a deployment")
Expect(d).NotTo(BeNil(), "expected a deployment but none returned")
service := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: f.Namespace,
},
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
{
Name: "http",
Port: 80,
TargetPort: intstr.FromInt(80),
Protocol: corev1.ProtocolTCP,
},
},
Selector: map[string]string{
"app": name,
},
},
}
s := f.EnsureService(service)
Expect(s).NotTo(BeNil(), "expected a service but none returned")
err = WaitForEndpoints(f.KubeClientSet, DefaultTimeout, name, f.Namespace, replicas)
Expect(err).NotTo(HaveOccurred(), "failed to wait for endpoints to become ready")
}
// NewSlowEchoDeployment creates a new deployment of the slow echo server image in a particular namespace.
func (f *Framework) NewSlowEchoDeployment() {
f.NewDeployment("slowecho", "breunigs/slowechoserver", 8080, 1)
data := map[string]string{}
data["default.conf"] = `#
server {
access_log on;
access_log /dev/stdout;
listen 80;
location / {
echo ok;
}
location ~ ^/sleep/(?<sleepTime>[0-9]+)$ {
echo_sleep $sleepTime;
echo "ok after $sleepTime seconds";
}
}
// NewHttpbinDeployment creates a new single replica deployment of the httpbin image in a particular namespace.
func (f *Framework) NewHttpbinDeployment() {
f.NewDeployment("httpbin", "kennethreitz/httpbin", 80, 1)
`
_, err := f.KubeClientSet.CoreV1().ConfigMaps(f.Namespace).Create(&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: SlowEchoService,
Namespace: f.Namespace,
},
Data: data,
})
Expect(err).NotTo(HaveOccurred(), "failed to create a deployment")
deployment := newDeployment(SlowEchoService, f.Namespace, "openresty/openresty:1.15.8.2-alpine", 80, 1,
nil,
[]corev1.VolumeMount{
{
Name: SlowEchoService,
MountPath: "/etc/nginx/conf.d",
ReadOnly: true,
},
},
[]corev1.Volume{
{
Name: SlowEchoService,
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: SlowEchoService,
},
},
},
},
},
)
d, err := f.EnsureDeployment(deployment)
Expect(err).NotTo(HaveOccurred(), "failed to create a deployment")
Expect(d).NotTo(BeNil(), "expected a deployment but none returned")
service := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: SlowEchoService,
Namespace: f.Namespace,
},
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
{
Name: "http",
Port: 80,
TargetPort: intstr.FromInt(80),
Protocol: corev1.ProtocolTCP,
},
},
Selector: map[string]string{
"app": SlowEchoService,
},
},
}
s := f.EnsureService(service)
Expect(s).NotTo(BeNil(), "expected a service but none returned")
err = WaitForEndpoints(f.KubeClientSet, DefaultTimeout, SlowEchoService, f.Namespace, 1)
Expect(err).NotTo(HaveOccurred(), "failed to wait for endpoints to become ready")
}
// NewDeployment creates a new deployment in a particular namespace.
func (f *Framework) NewDeployment(name, image string, port int32, replicas int32) {
func newDeployment(name, namespace, image string, port int32, replicas int32, command []string,
volumeMounts []corev1.VolumeMount, volumes []corev1.Volume) *appsv1.Deployment {
probe := &corev1.Probe{
InitialDelaySeconds: 5,
PeriodSeconds: 10,
InitialDelaySeconds: 1,
PeriodSeconds: 5,
SuccessThreshold: 1,
TimeoutSeconds: 1,
Handler: corev1.Handler{
@ -70,10 +313,10 @@ func (f *Framework) NewDeployment(name, image string, port int32, replicas int32
},
}
deployment := &appsv1.Deployment{
d := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: f.Namespace,
Namespace: namespace,
},
Spec: appsv1.DeploymentSpec{
Replicas: NewInt32(replicas),
@ -103,13 +346,31 @@ func (f *Framework) NewDeployment(name, image string, port int32, replicas int32
},
ReadinessProbe: probe,
LivenessProbe: probe,
VolumeMounts: volumeMounts,
},
},
Volumes: volumes,
},
},
},
}
if len(command) > 0 {
d.Spec.Template.Spec.Containers[0].Command = command
}
return d
}
// NewHttpbinDeployment creates a new single replica deployment of the httpbin image in a particular namespace.
func (f *Framework) NewHttpbinDeployment() {
f.NewDeployment(HTTPBinService, "ingress-controller/httpbin:dev", 80, 1)
}
// NewDeployment creates a new deployment in a particular namespace.
func (f *Framework) NewDeployment(name, image string, port int32, replicas int32) {
deployment := newDeployment(name, f.Namespace, image, port, replicas, nil, nil, nil)
d, err := f.EnsureDeployment(deployment)
Expect(err).NotTo(HaveOccurred(), "failed to create a deployment")
Expect(d).NotTo(BeNil(), "expected a deployment but none returned")
@ -151,3 +412,16 @@ func (f *Framework) DeleteDeployment(name string) error {
LabelSelector: labelSelectorToString(d.Spec.Selector.MatchLabels),
})
}
// ScaleDeploymentToZero scales a deployment with a particular name and waits for the pods to be deleted
func (f *Framework) ScaleDeploymentToZero(name string) {
d, err := f.KubeClientSet.AppsV1().Deployments(f.Namespace).Get(name, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred(), "failed to get a deployment")
Expect(d).NotTo(BeNil(), "expected a deployment but none returned")
d.Spec.Replicas = NewInt32(0)
d, err = f.EnsureDeployment(d)
Expect(err).NotTo(HaveOccurred(), "waiting deployment scale to 0")
Expect(d).NotTo(BeNil(), "expected a deployment but none returned")
}

View file

@ -110,9 +110,6 @@ func (f *Framework) BeforeEach() {
LabelSelector: "app.kubernetes.io/name=ingress-nginx",
})
Expect(err).NotTo(HaveOccurred())
// we wait for any change in the informers and SSL certificate generation
time.Sleep(5 * time.Second)
}
// AfterEach deletes the namespace, after reading its events.

View file

@ -122,7 +122,7 @@ func (f *Framework) EnsureDeployment(deployment *appsv1.Deployment) (*appsv1.Dep
// WaitForPodsReady waits for a given amount of time until a group of Pods is running in the given namespace.
func WaitForPodsReady(kubeClientSet kubernetes.Interface, timeout time.Duration, expectedReplicas int, namespace string, opts metav1.ListOptions) error {
return wait.Poll(2*time.Second, timeout, func() (bool, error) {
return wait.Poll(Poll, timeout, func() (bool, error) {
pl, err := kubeClientSet.CoreV1().Pods(namespace).List(opts)
if err != nil {
return false, nil
@ -145,7 +145,7 @@ func WaitForPodsReady(kubeClientSet kubernetes.Interface, timeout time.Duration,
// WaitForPodsDeleted waits for a given amount of time until a group of Pods are deleted in the given namespace.
func WaitForPodsDeleted(kubeClientSet kubernetes.Interface, timeout time.Duration, namespace string, opts metav1.ListOptions) error {
return wait.Poll(2*time.Second, timeout, func() (bool, error) {
return wait.Poll(Poll, timeout, func() (bool, error) {
pl, err := kubeClientSet.CoreV1().Pods(namespace).List(opts)
if err != nil {
return false, nil
@ -163,12 +163,15 @@ func WaitForEndpoints(kubeClientSet kubernetes.Interface, timeout time.Duration,
if expectedEndpoints == 0 {
return nil
}
return wait.Poll(2*time.Second, timeout, func() (bool, error) {
return wait.Poll(Poll, timeout, func() (bool, error) {
endpoint, err := kubeClientSet.CoreV1().Endpoints(ns).Get(name, metav1.GetOptions{})
if k8sErrors.IsNotFound(err) {
return false, nil
}
Expect(err).NotTo(HaveOccurred())
if len(endpoint.Subsets) == 0 || len(endpoint.Subsets[0].Addresses) == 0 {
return false, nil
}