diff --git a/pkg/controller/fixture.go b/pkg/controller/fixture.go index d25d6974..8b5c94ad 100644 --- a/pkg/controller/fixture.go +++ b/pkg/controller/fixture.go @@ -48,19 +48,26 @@ func newFixture(c *flaggerv1.Canary) fixture { if c == nil { c = newTestCanary() } - flaggerClient := fakeFlagger.NewSimpleClientset(c, newTestMetricTemplate()) - // init kube clientset and register mock objects + // init Flagger clientset and register objects + flaggerClient := fakeFlagger.NewSimpleClientset( + c, + newTestMetricTemplate(), + newTestAlertProvider(), + ) + + // init Kubernetes clientset and register objects kubeClient := fake.NewSimpleClientset( newTestDeployment(), newTestService(), newTestHPA(), - NewTestConfigMap(), - NewTestConfigMapEnv(), - NewTestConfigMapVol(), - NewTestSecret(), - NewTestSecretEnv(), - NewTestSecretVol(), + newTestConfigMap(), + newTestConfigMapEnv(), + newTestConfigMapVol(), + newTestSecret(), + newTestSecretEnv(), + newTestSecretVol(), + newTestAlertProviderSecret(), ) logger, _ := logger.NewLogger("debug") @@ -107,6 +114,7 @@ func newFixture(c *flaggerv1.Canary) fixture { ctrl.flaggerSynced = alwaysReady ctrl.flaggerInformers.CanaryInformer.Informer().GetIndexer().Add(c) ctrl.flaggerInformers.MetricInformer.Informer().GetIndexer().Add(newTestMetricTemplate()) + ctrl.flaggerInformers.AlertInformer.Informer().GetIndexer().Add(newTestAlertProvider()) meshRouter := rf.MeshRouter("istio") @@ -122,7 +130,7 @@ func newFixture(c *flaggerv1.Canary) fixture { } } -func NewTestConfigMap() *corev1.ConfigMap { +func newTestConfigMap() *corev1.ConfigMap { return &corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{APIVersion: corev1.SchemeGroupVersion.String()}, ObjectMeta: metav1.ObjectMeta{ @@ -135,7 +143,7 @@ func NewTestConfigMap() *corev1.ConfigMap { } } -func NewTestConfigMapV2() *corev1.ConfigMap { +func newTestConfigMapV2() *corev1.ConfigMap { return &corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{APIVersion: corev1.SchemeGroupVersion.String()}, ObjectMeta: metav1.ObjectMeta{ @@ -149,7 +157,7 @@ func NewTestConfigMapV2() *corev1.ConfigMap { } } -func NewTestConfigMapEnv() *corev1.ConfigMap { +func newTestConfigMapEnv() *corev1.ConfigMap { return &corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{APIVersion: corev1.SchemeGroupVersion.String()}, ObjectMeta: metav1.ObjectMeta{ @@ -162,7 +170,7 @@ func NewTestConfigMapEnv() *corev1.ConfigMap { } } -func NewTestConfigMapVol() *corev1.ConfigMap { +func newTestConfigMapVol() *corev1.ConfigMap { return &corev1.ConfigMap{ TypeMeta: metav1.TypeMeta{APIVersion: corev1.SchemeGroupVersion.String()}, ObjectMeta: metav1.ObjectMeta{ @@ -175,7 +183,7 @@ func NewTestConfigMapVol() *corev1.ConfigMap { } } -func NewTestSecret() *corev1.Secret { +func newTestSecret() *corev1.Secret { return &corev1.Secret{ TypeMeta: metav1.TypeMeta{APIVersion: corev1.SchemeGroupVersion.String()}, ObjectMeta: metav1.ObjectMeta{ @@ -191,7 +199,7 @@ func NewTestSecret() *corev1.Secret { } } -func NewTestSecretV2() *corev1.Secret { +func newTestSecretV2() *corev1.Secret { return &corev1.Secret{ TypeMeta: metav1.TypeMeta{APIVersion: corev1.SchemeGroupVersion.String()}, ObjectMeta: metav1.ObjectMeta{ @@ -207,7 +215,7 @@ func NewTestSecretV2() *corev1.Secret { } } -func NewTestSecretEnv() *corev1.Secret { +func newTestSecretEnv() *corev1.Secret { return &corev1.Secret{ TypeMeta: metav1.TypeMeta{APIVersion: corev1.SchemeGroupVersion.String()}, ObjectMeta: metav1.ObjectMeta{ @@ -221,7 +229,7 @@ func NewTestSecretEnv() *corev1.Secret { } } -func NewTestSecretVol() *corev1.Secret { +func newTestSecretVol() *corev1.Secret { return &corev1.Secret{ TypeMeta: metav1.TypeMeta{APIVersion: corev1.SchemeGroupVersion.String()}, ObjectMeta: metav1.ObjectMeta{ @@ -702,3 +710,34 @@ func newTestMetricTemplate() *flaggerv1.MetricTemplate { } return template } + +func newTestAlertProviderSecret() *corev1.Secret { + return &corev1.Secret{ + TypeMeta: metav1.TypeMeta{APIVersion: corev1.SchemeGroupVersion.String()}, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "alert-secret", + }, + Type: corev1.SecretTypeOpaque, + Data: map[string][]byte{ + "address": []byte("http://mock.slack"), + }, + } +} + +func newTestAlertProvider() *flaggerv1.AlertProvider { + return &flaggerv1.AlertProvider{ + TypeMeta: metav1.TypeMeta{APIVersion: flaggerv1.SchemeGroupVersion.String()}, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "slack", + }, + Spec: flaggerv1.AlertProviderSpec{ + Type: "slack", + Address: "http://fake.slack", + SecretRef: &corev1.LocalObjectReference{ + Name: "alert-secret", + }, + }, + } +} diff --git a/pkg/controller/scheduler_test.go b/pkg/controller/scheduler_test.go index 6c1e90d1..f49a44f5 100644 --- a/pkg/controller/scheduler_test.go +++ b/pkg/controller/scheduler_test.go @@ -1,13 +1,18 @@ package controller import ( + "encoding/json" "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" "testing" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1" + "github.com/weaveworks/flagger/pkg/notifier" ) func TestScheduler_Init(t *testing.T) { @@ -227,13 +232,13 @@ func TestScheduler_Promotion(t *testing.T) { // detect pod spec changes mocks.ctrl.advanceCanary("podinfo", "default", true) - config2 := NewTestConfigMapV2() + config2 := newTestConfigMapV2() _, err = mocks.kubeClient.CoreV1().ConfigMaps("default").Update(config2) if err != nil { t.Fatal(err.Error()) } - secret2 := NewTestSecretV2() + secret2 := newTestSecretV2() _, err = mocks.kubeClient.CoreV1().Secrets("default").Update(secret2) if err != nil { t.Fatal(err.Error()) @@ -631,3 +636,53 @@ func TestScheduler_TargetPortName(t *testing.T) { } } + +func TestScheduler_Alerts(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + b, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Fatal(err) + } + var payload = notifier.SlackPayload{} + err = json.Unmarshal(b, &payload) + if err != nil { + t.Fatal(err) + } + if payload.Attachments[0].AuthorName != "podinfo.default" { + t.Fatal("wrong author name") + } + })) + defer ts.Close() + + canary := newTestCanary() + canary.Spec.CanaryAnalysis.Alerts = []flaggerv1.CanaryAlert{ + { + Name: "slack-dev", + Severity: "info", + ProviderRef: flaggerv1.CrossNamespaceObjectReference{ + Name: "slack", + Namespace: "default", + }, + }, + { + Name: "slack-prod", + Severity: "info", + ProviderRef: flaggerv1.CrossNamespaceObjectReference{ + Name: "slack", + }, + }, + } + mocks := newFixture(canary) + + secret := newTestAlertProviderSecret() + secret.Data = map[string][]byte{ + "address": []byte(ts.URL), + } + _, err := mocks.kubeClient.CoreV1().Secrets("default").Update(secret) + if err != nil { + t.Fatal(err.Error()) + } + + // init canary and send alerts + mocks.ctrl.advanceCanary("podinfo", "default", true) +}