Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 32 additions & 4 deletions test/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ limitations under the License.
package test

import (
"fmt"
"strings"

"github.com/knative/pkg/test/logging"
"github.com/knative/pkg/test/spoof"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
k8styped "k8s.io/client-go/kubernetes/typed/core/v1"
Expand Down Expand Up @@ -67,7 +71,7 @@ func BuildClientConfig(kubeConfigPath string, clusterName string) (*rest.Config,

// UpdateConfigMap updates the config map for specified @name with values
func (client *KubeClient) UpdateConfigMap(name string, configName string, values map[string]string) error {
configMap, err := client.getConfigMap(name).Get(configName, metav1.GetOptions{})
configMap, err := client.GetConfigMap(name).Get(configName, metav1.GetOptions{})
if err != nil {
return err
}
Expand All @@ -76,11 +80,35 @@ func (client *KubeClient) UpdateConfigMap(name string, configName string, values
configMap.Data[key] = value
}

_, err = client.getConfigMap(name).Update(configMap)
_, err = client.GetConfigMap(name).Update(configMap)
return err
}

// getConfigMap gets the knative serving config map.
func (client *KubeClient) getConfigMap(name string) k8styped.ConfigMapInterface {
// GetConfigMap gets the knative serving config map.
func (client *KubeClient) GetConfigMap(name string) k8styped.ConfigMapInterface {
return client.Kube.CoreV1().ConfigMaps(name)
}

// CreatePod will create a Pod
func (client *KubeClient) CreatePod(pod *corev1.Pod) (*corev1.Pod, error) {
pods := client.Kube.CoreV1().Pods(pod.GetNamespace())
return pods.Create(pod)
}

// PodLogs returns Pod logs for given Pod and Container
func (client *KubeClient) PodLogs(podName, containerName string) ([]byte, error) {
pods := client.Kube.CoreV1().Pods(Flags.Namespace)
podList, err := pods.List(metav1.ListOptions{})
if err != nil {
return nil, err
}
for _, pod := range podList.Items {
if strings.Contains(pod.Name, podName) {
result := pods.GetLogs(pod.Name, &corev1.PodLogOptions{
Container: containerName,
}).Do()
return result.Raw()
}
}
return nil, fmt.Errorf("Could not find logs for %s/%s", podName, containerName)
}
95 changes: 95 additions & 0 deletions test/crd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
Copyright 2019 The Knative 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.
*/

// This file contains functions that construct boilerplate CRD definitions.

package test

import (
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
nginxPort = 80
nginxName = "nginx"
nginxImage = "nginx:1.7.9"
)

// ServiceAccount returns ServiceAccount object in given namespace
func ServiceAccount(name string, namespace string) *corev1.ServiceAccount {
return &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
}
}

// ClusterRoleBinding returns ClusterRoleBinding for given subject and role
func ClusterRoleBinding(name string, namespace string, serviceAccount string, role string) *rbacv1.ClusterRoleBinding {
return &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Subjects: []rbacv1.Subject{
{
Kind: "ServiceAccount",
Name: serviceAccount,
Namespace: namespace,
},
},
RoleRef: rbacv1.RoleRef{
Kind: "ClusterRole",
Name: role,
APIGroup: "rbac.authorization.k8s.io",
},
}
}

// CoreV1ObjectReference returns a corev1.ObjectReference for the given name, kind and apiversion
func CoreV1ObjectReference(kind, apiversion, name string) *corev1.ObjectReference {
return &corev1.ObjectReference{
Kind: kind,
APIVersion: apiversion,
Name: name,
}
}

// NginxPod returns nginx pod defined in given namespace
func NginxPod(namespace string) *corev1.Pod {
return &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: nginxName,
Namespace: namespace,
Annotations: map[string]string{"sidecar.istio.io/inject": "true"},
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: nginxName,
Image: nginxImage,
Ports: []corev1.ContainerPort{
{
ContainerPort: nginxPort,
},
},
},
},
},
}
}
15 changes: 15 additions & 0 deletions test/e2e_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ package test

import (
"flag"
"fmt"
"os"
"os/user"
"path"
)
Expand All @@ -37,6 +39,8 @@ type EnvironmentFlags struct {
IngressEndpoint string // Host to use for ingress endpoint
LogVerbose bool // Enable verbose logging
EmitMetrics bool // Emit metrics
DockerRepo string // Docker repo (defaults to $KO_DOCKER_REPO)
Tag string // Tag for test images
}

func initializeFlags() *EnvironmentFlags {
Expand All @@ -63,5 +67,16 @@ func initializeFlags() *EnvironmentFlags {
flag.BoolVar(&f.EmitMetrics, "emitmetrics", false,
"Set this flag to true if you would like tests to emit metrics, e.g. latency of resources being realized in the system.")

defaultRepo := os.Getenv("KO_DOCKER_REPO")
flag.StringVar(&f.DockerRepo, "dockerrepo", defaultRepo,
"Provide the uri of the docker repo you have uploaded the test image to using `uploadtestimage.sh`. Defaults to $KO_DOCKER_REPO")

flag.StringVar(&f.Tag, "tag", "e2e", "Provide the version tag for the test images.")

return &f
}

// ImagePath is a helper function to prefix image name with repo and suffix with tag
func ImagePath(name string) string {
return fmt.Sprintf("%s/%s:%s", Flags.DockerRepo, name, Flags.Tag)
}
31 changes: 30 additions & 1 deletion test/kube_checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package test
import (
"context"
"fmt"
"strings"
"time"

"github.com/knative/pkg/test/logging"
Expand All @@ -35,6 +36,7 @@ import (
const (
interval = 1 * time.Second
podTimeout = 8 * time.Minute
logTimeout = 1 * time.Minute
)

// WaitForDeploymentState polls the status of the Deployment called name
Expand Down Expand Up @@ -78,9 +80,36 @@ func GetConfigMap(client *KubeClient, namespace string) k8styped.ConfigMapInterf
return client.Kube.CoreV1().ConfigMaps(namespace)
}

// Returns a func that evaluates if a deployment has scaled to 0 pods
// DeploymentScaledToZeroFunc returns a func that evaluates if a deployment has scaled to 0 pods
func DeploymentScaledToZeroFunc() func(d *apiv1beta1.Deployment) (bool, error) {
return func(d *apiv1beta1.Deployment) (bool, error) {
return d.Status.ReadyReplicas == 0, nil
}
}

// WaitForLogContent waits until logs for given Pod/Container include the given content.
// If the content is not present within timeout it returns error.
func WaitForLogContent(client *KubeClient, podName, containerName, content string) error {
return wait.PollImmediate(interval, logTimeout, func() (bool, error) {
logs, err := client.PodLogs(podName, containerName)
if err != nil {
return true, err
}
return strings.Contains(string(logs), content), nil
})
}

// WaitForAllPodsRunning waits for all the pods to be in running state
func WaitForAllPodsRunning(client *KubeClient, namespace string) error {
return WaitForPodListState(client, PodsRunning, "PodsAreRunning", namespace)
}

// PodsRunning will check the status conditions of the pod list and return true all pods are Running
func PodsRunning(podList *corev1.PodList) (bool, error) {
for _, pod := range podList.Items {
if pod.Status.Phase != corev1.PodRunning && pod.Status.Phase != corev1.PodSucceeded {
return false, nil
}
}
return true, nil
}