e2e tests

feature/poll-multi-tags
Karolis Rusenas 2018-11-13 20:22:47 +00:00
parent bd00613e7e
commit 379affe794
2 changed files with 280 additions and 0 deletions

187
tests/acceptance_test.go Normal file
View File

@ -0,0 +1,187 @@
package tests
import (
"bytes"
"context"
"net/http"
"testing"
"time"
"github.com/keel-hq/keel/types"
apps_v1 "k8s.io/api/apps/v1"
"k8s.io/api/core/v1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
var dockerHub0150Webhook = `{
"push_data": {
"pushed_at": 1497467660,
"images": [],
"tag": "0.0.15",
"pusher": "karolisr"
},
"repository": {
"status": "Active",
"description": "",
"is_trusted": false,
"repo_url": "https://hub.docker.com/r/webhook-demo",
"owner": "karolisr",
"is_official": false,
"is_private": false,
"name": "keel",
"namespace": "karolisr",
"star_count": 0,
"comment_count": 0,
"date_created": 1497032538,
"repo_name": "karolisr/webhook-demo"
}
}`
func TestSemverUpdate(t *testing.T) {
// stop := make(chan struct{})
context, cancel := context.WithCancel(context.Background())
// defer close(ctx)
defer cancel()
go startKeel(context)
_, kcs := getKubernetesClient()
t.Run("UpdateThroughDockerHubWebhook", func(t *testing.T) {
testNamespace := createNamespaceForTest()
defer deleteTestNamespace(testNamespace)
dep := &apps_v1.Deployment{
meta_v1.TypeMeta{},
meta_v1.ObjectMeta{
Name: "deployment-1",
Namespace: testNamespace,
Labels: map[string]string{types.KeelPolicyLabel: "all"},
Annotations: map[string]string{},
},
apps_v1.DeploymentSpec{
Selector: &meta_v1.LabelSelector{
MatchLabels: map[string]string{
"app": "wd-1",
},
},
Template: v1.PodTemplateSpec{
ObjectMeta: meta_v1.ObjectMeta{
Labels: map[string]string{
"app": "wd-1",
"release": "1",
},
},
Spec: v1.PodSpec{
Containers: []v1.Container{
v1.Container{
Name: "wd-1",
Image: "karolisr/webhook-demo:0.0.14",
},
},
},
},
},
apps_v1.DeploymentStatus{},
}
_, err := kcs.AppsV1().Deployments(testNamespace).Create(dep)
if err != nil {
t.Fatalf("failed to create deployment: %s", err)
}
// giving some time to get started
// TODO: replace with a readiness check function to wait for 1/1 READY
time.Sleep(2 * time.Second)
// sending webhook
client := http.DefaultClient
buf := bytes.NewBufferString(dockerHub0150Webhook)
req, err := http.NewRequest("POST", "http://localhost:9300/v1/webhooks/dockerhub", buf)
if err != nil {
t.Fatalf("failed to create req: %s", err)
}
resp, err := client.Do(req)
if err != nil {
t.Errorf("failed to make a webhook request to keel: %s", err)
}
if resp.StatusCode != 200 {
t.Errorf("unexpected webhook response from keel: %d", resp.StatusCode)
}
time.Sleep(2 * time.Second)
updated, err := kcs.AppsV1().Deployments(testNamespace).Get(dep.ObjectMeta.Name, meta_v1.GetOptions{})
if err != nil {
t.Fatalf("failed to get deployment: %s", err)
}
if updated.Spec.Template.Spec.Containers[0].Image != "karolisr/webhook-demo:0.0.15" {
t.Errorf("expected 'karolisr/webhook-demo:0.0.15', got: '%s'", updated.Spec.Template.Spec.Containers[0].Image)
}
})
t.Run("UpdateThroughDockerHubPolling", func(t *testing.T) {
testNamespace := createNamespaceForTest()
defer deleteTestNamespace(testNamespace)
dep := &apps_v1.Deployment{
meta_v1.TypeMeta{},
meta_v1.ObjectMeta{
Name: "deployment-1",
Namespace: testNamespace,
Labels: map[string]string{
types.KeelPolicyLabel: "major",
types.KeelTriggerLabel: "poll",
},
Annotations: map[string]string{},
},
apps_v1.DeploymentSpec{
Selector: &meta_v1.LabelSelector{
MatchLabels: map[string]string{
"app": "wd-1",
},
},
Template: v1.PodTemplateSpec{
ObjectMeta: meta_v1.ObjectMeta{
Labels: map[string]string{
"app": "wd-1",
"release": "1",
},
},
Spec: v1.PodSpec{
Containers: []v1.Container{
v1.Container{
Name: "wd-1",
Image: "keelhq/push-workflow-example:0.1.0-dev",
},
},
},
},
},
apps_v1.DeploymentStatus{},
}
_, err := kcs.AppsV1().Deployments(testNamespace).Create(dep)
if err != nil {
t.Fatalf("failed to create deployment: %s", err)
}
// giving some time to get started
// TODO: replace with a readiness check function to wait for 1/1 READY
time.Sleep(2 * time.Second)
updated, err := kcs.AppsV1().Deployments(testNamespace).Get(dep.ObjectMeta.Name, meta_v1.GetOptions{})
if err != nil {
t.Fatalf("failed to get deployment: %s", err)
}
if updated.Spec.Template.Spec.Containers[0].Image != "keelhq/push-workflow-example:0.5.0-dev" {
t.Errorf("expected 'keelhq/push-workflow-example:0.5.0-dev', got: '%s'", updated.Spec.Template.Spec.Containers[0].Image)
}
})
}

93
tests/helpers.go Normal file
View File

@ -0,0 +1,93 @@
package tests
import (
"context"
"flag"
"os"
"os/exec"
"path/filepath"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
// load the gcp plugin (required to authenticate against GKE clusters).
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
log "github.com/sirupsen/logrus"
)
var kubeConfig = flag.String("kubeconfig", "", "Path to Kubernetes config file")
func getKubeConfig() string {
if *kubeConfig != "" {
return *kubeConfig
}
return filepath.Join(os.Getenv("HOME"), ".kube", "config")
}
func getKubernetesClient() (*rest.Config, *kubernetes.Clientset) {
// use the current context in kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", getKubeConfig())
if err != nil {
panic(err.Error())
}
// create the clientset
clientSet, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
return config, clientSet
}
func createNamespaceForTest() string {
_, clientset := getKubernetesClient()
ns := &v1.Namespace{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "keel-e2e-test-",
},
}
cns, err := clientset.CoreV1().Namespaces().Create(ns)
if err != nil {
panic(err)
}
log.Infof("test namespace '%s' created", cns.Name)
return cns.Name
}
func deleteTestNamespace(namespace string) error {
defer log.Infof("test namespace '%s' deleted", namespace)
_, clientset := getKubernetesClient()
deleteOptions := metav1.DeleteOptions{}
return clientset.CoreV1().Namespaces().Delete(namespace, &deleteOptions)
}
func startKeel(ctx context.Context) error {
log.Info("keel started")
defer log.Info("keel stopped")
cmd := "keel"
args := []string{"--no-incluster", "--kubeconfig", getKubeConfig()}
c := exec.CommandContext(ctx, cmd, args...)
c.Stdout = os.Stdout
c.Stderr = os.Stderr
go func() {
<-ctx.Done()
err := c.Process.Kill()
if err != nil {
log.Errorf("failed to kill keel process: %s", err)
}
}()
return c.Run()
}