Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ cover.out
.vscode
.idea
.DS_Store
e2e/logs
23 changes: 23 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ fallthrough: submodules
# integration tests
e2e.run: test-integration

# Setup E2E tests based on e2e-framework
E2E_FILTER ?= .*
E2E_CONTROLLER ?= $(BUILD_REGISTRY)/$(subst crossplane-,crossplane/,$(PROJECT_NAME)):latest
E2E_XPKG_TAR ?= $(XPKG_OUTPUT_DIR)/$(PLATFORM)/$(PROJECT_NAME)-$(VERSION).xpkg
E2E_XPKG_TAG ?= e2e/$(PROJECT_NAME):$(VERSION)

export E2E_IMAGES = {"crossplane/provider-cortex":"${E2E_XPKG_TAG}"}


# Run integration tests.
test-integration: $(KIND) $(KUBECTL) $(UP) $(HELM3)
@$(INFO) running integration tests using kind $(KIND_VERSION)
Expand Down Expand Up @@ -104,6 +113,20 @@ dev-clean: $(KIND) $(KUBECTL)

.PHONY: submodules fallthrough test-integration run dev dev-clean

.PHOBY: e2e.alternative-run

e2e.alternative-run: $(KIND) $(HELM3) build e2e.alternative-run.load-image
@$(INFO) running e2e tests
@echo "E2E_IMAGES=$$E2E_IMAGES"
go test -v $(PROJECT_REPO)/e2e/... -tags=e2e -count=1 -test.v -run '$(E2E_FILTER)'
@$(OK) e2e tests passed

e2e.alternative-run.load-image:

$(eval DIGEST=$(shell docker image load -i $(E2E_XPKG_TAR) | cut -d ":" -f3))

docker tag $(DIGEST) $(E2E_XPKG_TAG)

# ====================================================================================
# Special Targets

Expand Down
27 changes: 27 additions & 0 deletions e2e/alerts_v1alpha1_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//go:build e2e

package e2e

import (
"fmt"
"testing"

"github.com/crossplane-contrib/xp-testing/pkg/resources"
"sigs.k8s.io/e2e-framework/pkg/features"

"github.com/swisscom/provider-cortex/apis/alerts/v1alpha1"
)

func Test_AlertManagerConfiguration_v1alpha1(t *testing.T) {

resource := resources.NewResourceTestConfig(&v1alpha1.AlertManagerConfiguration{}, "AlertManagerConfiguration")

fB := features.New(fmt.Sprintf("%v", resource.Kind))
fB.WithLabel("kind", resource.Kind)
fB.Setup(resource.Setup)
fB.Assess("create", resource.AssessCreate)
fB.Assess("delete", resource.AssessDelete)

testenv.Test(t, fB.Feature())

}
24 changes: 24 additions & 0 deletions e2e/crs/AlertManagerConfiguration/configuration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: alerts.cortex.crossplane.io/v1alpha1
kind: AlertManagerConfiguration
metadata:
name: example-configuration
spec:
forProvider:
template_files:
default_template: |
{{ define "__alertmanager" }}AlertManager{{ end }}
{{ define "__alertmanagerURL" }}{{ .ExternalURL }}/#/alerts?receiver={{ .Receiver | urlquery }}{{ end }}
alertmanager_config: |
global:
smtp_smarthost: 'localhost:25'
smtp_from: 'youraddress@example.org'
templates:
- 'default_template'
route:
receiver: example-email
receivers:
- name: example-email
email_configs:
- to: 'youraddress@example.org'
providerConfigRef:
name: provider-cortex
20 changes: 20 additions & 0 deletions e2e/crs/RuleGroup/rulegroup.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: rules.cortex.crossplane.io/v1alpha1
kind: RuleGroup
metadata:
name: example-rulegroup
spec:
forProvider:
namespace: example-namespace
interval: 10m
rules:
- record: instance_path:request_failures:rate5m
expr: rate(request_failures_total{job="myjob"}[5m])
- alert: HighCPUUtilization
expr: avg(node_cpu{mode="system"}) > 80
for: 5m
annotations:
annotation_name: test
labels:
label_name: test
providerConfigRef:
name: provider-cortex
48 changes: 48 additions & 0 deletions e2e/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//go:build e2e

package e2e

import (
"os"
"testing"

runtime "k8s.io/apimachinery/pkg/runtime"

xpv1alpha1 "github.com/crossplane/crossplane/apis/pkg/v1alpha1"
"github.com/swisscom/provider-cortex/apis"
"sigs.k8s.io/e2e-framework/pkg/env"

"github.com/crossplane-contrib/xp-testing/pkg/images"
"github.com/crossplane-contrib/xp-testing/pkg/logging"
"github.com/crossplane-contrib/xp-testing/pkg/setup"
)

var testenv env.Environment

func TestMain(m *testing.M) {
var verbosity = 4
logging.EnableVerboseLogging(&verbosity)
testenv = env.NewParallel()

key := "crossplane/provider-cortex"
imgs := images.GetImagesFromEnvironmentOrPanic(key, &key)
clusterSetup := setup.ClusterSetup{
Name: "cortex",
Images: imgs,
ControllerConfig: &xpv1alpha1.ControllerConfig{
Spec: xpv1alpha1.ControllerConfigSpec{
Image: &imgs.Package,
// Raise sync interval to speed up tests
// add debug output, in case necessary for debugging in e.g. CI
Args: []string{"--debug", "--sync=5s"},
},
},
SecretData: nil,
AddToSchemaFuncs: []func(s *runtime.Scheme) error{apis.AddToScheme},
CrossplaneVersion: "1.13.2",
}

clusterSetup.Configure(testenv)
testenv.Setup(installCortex("v1.15.2"))
os.Exit(testenv.Run(m))
}
7 changes: 7 additions & 0 deletions e2e/provider/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: cortex.crossplane.io/v1alpha1
kind: ProviderConfig
metadata:
name: provider-cortex
spec:
tenantId: example-tenant
address: http://cortex.default.svc:9009
27 changes: 27 additions & 0 deletions e2e/rules_v1alpha1_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//go:build e2e

package e2e

import (
"fmt"
"testing"

"github.com/crossplane-contrib/xp-testing/pkg/resources"
"sigs.k8s.io/e2e-framework/pkg/features"

"github.com/swisscom/provider-cortex/apis/rules/v1alpha1"
)

func Test_RuleGroup_v1alpha1(t *testing.T) {

resource := resources.NewResourceTestConfig(&v1alpha1.RuleGroup{}, "RuleGroup")

fB := features.New(fmt.Sprintf("%v", resource.Kind))
fB.WithLabel("kind", resource.Kind)
fB.Setup(resource.Setup)
fB.Assess("create", resource.AssessCreate)
fB.Assess("delete", resource.AssessDelete)

testenv.Test(t, fB.Feature())

}
117 changes: 117 additions & 0 deletions e2e/setup_cortex.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package e2e

import (
"context"
"io"
"log"
"net/http"
"strings"
"time"

"github.com/crossplane-contrib/xp-testing/pkg/xpenvfuncs"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/klog/v2"
"sigs.k8s.io/e2e-framework/klient/decoder"
"sigs.k8s.io/e2e-framework/klient/k8s/resources"
"sigs.k8s.io/e2e-framework/klient/wait"
"sigs.k8s.io/e2e-framework/klient/wait/conditions"
"sigs.k8s.io/e2e-framework/pkg/env"
"sigs.k8s.io/e2e-framework/pkg/envconf"
"sigs.k8s.io/e2e-framework/pkg/envfuncs"
)

const (
cortexNamespace = "default"
bucketCreatorPodLabel = "app=minio-bucket-creator"
)

func installCortex(cortexVersion string) env.Func {
return xpenvfuncs.Compose(
xpenvfuncs.IgnoreMatchedErr(envfuncs.CreateNamespace(cortexNamespace), errors.IsAlreadyExists),
installCortexManifests(cortexVersion),
waitForCortexToBeAvailable(cortexNamespace, bucketCreatorPodLabel),
)
}

func waitForCortexToBeAvailable(namespace, cortexPodLabel string) env.Func {
return func(ctx context.Context, config *envconf.Config) (context.Context, error) {
res := config.Client().Resources()
res = res.WithNamespace(namespace)

c := conditions.New(res)
var pods v1.PodList

err := res.List(ctx, &pods, resources.WithLabelSelector(bucketCreatorPodLabel))
if err != nil {
return nil, err
}
klog.V(4).Info("Waiting for Cortex to become available")
for i := range pods.Items {
err := wait.For(
c.PodPhaseMatch(&pods.Items[i], v1.PodSucceeded),
wait.WithTimeout(8*time.Minute), wait.WithImmediate())
if err != nil {
return nil, err
}

}
klog.V(4).Info("Cortex has become available")
return ctx, nil
}
}

func installCortexManifests(cortexVersion string) env.Func {
return func(ctx context.Context, config *envconf.Config) (context.Context, error) {
manifest, err := downloadManifest()
if err != nil {
return ctx, err
}
r, err := resources.New(config.Client().RESTConfig())
if err != nil {
return ctx, err
}
err = decoder.DecodeEach(
ctx,
strings.NewReader(manifest),
decoder.IgnoreErrorHandler(decoder.CreateHandler(r), errors.IsAlreadyExists),
decoder.MutateNamespace(cortexNamespace),
)

if err != nil {
return ctx, err
}
return ctx, nil
}
}

func downloadManifest() (string, error) {
url := "https://raw.githubusercontent.com/janwillies/cortex-cue/main/generated.yaml"
req, err := http.NewRequestWithContext(context.TODO(), http.MethodGet, url, nil)

if err != nil {
return "", err
}

client := http.DefaultClient
res, err := client.Do(req)

if err != nil {
return "", err
}
defer func() {
err := res.Body.Close()
if err != nil {
log.Fatal(err)
}
}()
d, err := io.ReadAll(res.Body)
if err != nil {
return "", err
}
if res.StatusCode != http.StatusOK {
return "", err
}
manifests := string(d)
return manifests, nil
}
Loading