Skip to content

Commit

Permalink
e2e: Add e2e test suite
Browse files Browse the repository at this point in the history
Adds a new e2e test suite based on the MGC repo test suite with basic
single cluster test for "simple" and "loadbalanced" type records.

Adds a new make target `make test-e2e` to execute the test suite using
AWS or GCP providers:

```
make test-e2e TEST_DNS_MANAGED_ZONE_NAME=dev-mz-aws TEST_DNS_ZONE_DOMAIN_NAME=mn.hcpapps.net TEST_DNS_NAMESPACE=dnstest TEST_DNS_PROVIDER=aws
make test-e2e TEST_DNS_MANAGED_ZONE_NAME=dev-mz-gcp TEST_DNS_ZONE_DOMAIN_NAME=mn.google.hcpapps.net TEST_DNS_NAMESPACE=dnstest TEST_DNS_PROVIDER=gcp
```
  • Loading branch information
mikenairn committed Mar 11, 2024
1 parent bb2285d commit ab616d0
Show file tree
Hide file tree
Showing 6 changed files with 369 additions and 11 deletions.
11 changes: 11 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ test-unit: manifests generate fmt vet ## Run unit tests.
test-integration: manifests generate fmt vet envtest ## Run integration tests.
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./internal/controller... -tags=integration -coverprofile cover-integration.out

.PHONY: test-e2e
test-e2e: ginkgo
$(GINKGO) -tags=e2e -v ./test/e2e

.PHONY: local-setup
local-setup: DEPLOY=false
local-setup: TEST_NAMESPACE=dnstest
Expand Down Expand Up @@ -247,6 +251,7 @@ OPENSHIFT_GOIMPORTS ?= $(LOCALBIN)/openshift-goimports
KIND = $(LOCALBIN)/kind
ACT = $(LOCALBIN)/act
YQ = $(LOCALBIN)/yq
GINKGO ?= $(LOCALBIN)/ginkgo

## Tool Versions
KUSTOMIZE_VERSION ?= v5.0.1
Expand All @@ -255,6 +260,7 @@ OPENSHIFT_GOIMPORTS_VERSION ?= c70783e636f2213cac683f6865d88c5edace3157
KIND_VERSION = v0.20.0
ACT_VERSION = latest
YQ_VERSION := v4.34.2
GINKGO_VERSION ?= v2.13.2

.PHONY: kustomize
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. If wrong version is installed, it will be removed before downloading.
Expand Down Expand Up @@ -313,6 +319,11 @@ yq: $(YQ) ## Download yq locally if necessary.
$(YQ): $(LOCALBIN)
GOBIN=$(LOCALBIN) go install github.com/mikefarah/yq/v4@$(YQ_VERSION)

.PHONY: ginkgo
ginkgo: $(GINKGO) ## Download ginkgo locally if necessary
$(GINKGO): $(LOCALBIN)
GOBIN=$(LOCALBIN) go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo@$(GINKGO_VERSION)

.PHONY: bundle
bundle: manifests manifests-gen-base-csv kustomize operator-sdk ## Generate bundle manifests and metadata, then validate generated files.
$(OPERATOR_SDK) generate kustomize manifests -q
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,21 @@ kubectl logs -f deployments/dns-operator-controller-manager -n dns-operator-syst

## Development

### E2E Test Suite

The e2e test suite can be executed against any cluster running the DNS Operator with configuration added for any supported provider.

```
make test-e2e TEST_DNS_MANAGED_ZONE_NAME=<My managed zone name> TEST_DNS_ZONE_DOMAIN_NAME=<My domain name> TEST_DNS_NAMESPACE=<My test namesapace> TEST_DNS_PROVIDER=<aws|gcp>
```

| Environment Variable | Description |
|----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|
| TEST_DNS_MANAGED_ZONE_NAME | Name of the managed zone relevant for the test domain (TEST_DNS_ZONE_DOMAIN_NAME). If using local-setup Managed zones, one of [dev-mz-aws; dev-mz-gcp] |
| TEST_DNS_ZONE_DOMAIN_NAME | Domain name being used for the test, must match the domain of the managed zone (TEST_DNS_MANAGED_ZONE_NAME) |
| TEST_DNS_NAMESPACE | The namesapce to run the test in, must be the same namesapce as the TEST_DNS_MANAGED_ZONE_NAME |
| TEST_DNS_PROVIDER | DNS Provider currently being tested, one of [aws; gcp] |

### Modifying the API definitions
If you are editing the API definitions, generate the manifests such as CRs or CRDs using:

Expand Down
9 changes: 5 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ go 1.21

require (
github.com/aws/aws-sdk-go v1.44.311
github.com/go-logr/logr v1.2.4
github.com/onsi/ginkgo/v2 v2.11.0
github.com/onsi/gomega v1.27.10
github.com/go-logr/logr v1.3.0
github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e
github.com/onsi/ginkgo/v2 v2.13.2
github.com/onsi/gomega v1.30.0
github.com/prometheus/client_golang v1.17.0
google.golang.org/api v0.134.0
k8s.io/api v0.28.3
Expand Down Expand Up @@ -76,7 +77,7 @@ require (
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.13.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/term v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/time v0.3.0 // indirect
Expand Down
17 changes: 10 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,9 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo=
github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA=
Expand Down Expand Up @@ -377,6 +378,8 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsC
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
github.com/gookit/color v1.2.3/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg=
github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e h1:XmA6L9IPRdUr28a+SK/oMchGgQy159wvzXA5tJ7l+40=
github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e/go.mod h1:AFIo+02s+12CEg8Gzz9kzhCbmbq6JcKNrhHffCGA9z4=
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
Expand Down Expand Up @@ -573,16 +576,16 @@ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs=
github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
Expand Down Expand Up @@ -938,8 +941,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
Expand Down
213 changes: 213 additions & 0 deletions test/e2e/single_cluster_record_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
//go:build e2e

package e2e

import (
"context"
"strings"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gstruct"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
externaldnsendpoint "sigs.k8s.io/external-dns/endpoint"

"github.com/kuadrant/dns-operator/api/v1alpha1"
"github.com/kuadrant/dns-operator/internal/common/conditions"
)

var _ = Describe("Single Cluster Record Test", func() {
// testID is a randomly generated identifier for the test
// it is used to name resources and/or namespaces so different
// tests can be run in parallel in the same cluster
var testID string
// testDomainName generated domain for this test e.g. t-e2e-12345.e2e.hcpapps.net
var testDomainName string
// testHostname generated hostname for this test e.g. t-gw-mgc-12345.t-e2e-12345.e2e.hcpapps.net
var testHostname string

var dnsRecord *v1alpha1.DNSRecord
var geoCode string

BeforeEach(func(ctx SpecContext) {
testID = "t-single-" + GenerateName()
testDomainName = strings.Join([]string{testSuiteID, testZoneDomainName}, ".")
testHostname = strings.Join([]string{testID, testDomainName}, ".")

if testDNSProvider == "gcp" {
geoCode = "us-east1"
} else {
geoCode = "US"
}
})

AfterEach(func(ctx SpecContext) {
if dnsRecord != nil {
err := k8sClient.Delete(ctx, dnsRecord,
client.PropagationPolicy(metav1.DeletePropagationForeground))
Expect(client.IgnoreNotFound(err)).ToNot(HaveOccurred())
}
})

Context("simple", func() {
It("makes available a hostname that can be resolved", func(ctx SpecContext) {
By("creating a dns record")
testTargetIP := "127.0.0.1"
dnsRecord = &v1alpha1.DNSRecord{
ObjectMeta: metav1.ObjectMeta{
Name: testID,
Namespace: testNamespace,
},
Spec: v1alpha1.DNSRecordSpec{
ManagedZoneRef: &v1alpha1.ManagedZoneReference{
Name: testManagedZoneName,
},
Endpoints: []*externaldnsendpoint.Endpoint{
{
DNSName: testHostname,
Targets: []string{
testTargetIP,
},
RecordType: "A",
RecordTTL: 60,
},
},
},
}
err := k8sClient.Create(ctx, dnsRecord)
Expect(err).ToNot(HaveOccurred())

Eventually(func(g Gomega, ctx context.Context) {
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(dnsRecord), dnsRecord)
g.Expect(err).NotTo(HaveOccurred())
g.Expect(dnsRecord.Status.Conditions).To(
ContainElement(MatchFields(IgnoreExtras, Fields{
"Type": Equal(string(conditions.ConditionTypeReady)),
"Status": Equal(metav1.ConditionTrue),
})),
)
}, 300*time.Second, 10*time.Second, ctx).Should(Succeed())

By("ensuring the authoritative nameserver resolves the hostname")
// speed up things by using the authoritative nameserver
authoritativeResolver := ResolverForDomainName(testZoneDomainName)
Eventually(func(g Gomega, ctx context.Context) {
ips, err := authoritativeResolver.LookupHost(ctx, testHostname)
g.Expect(err).NotTo(HaveOccurred())
g.Expect(ips).To(ContainElement(testTargetIP))
}, 300*time.Second, 10*time.Second, ctx).Should(Succeed())
})
})

Context("loadbalanced", func() {
It("makes available a hostname that can be resolved", func(ctx SpecContext) {
By("creating a dns record")
testTargetIP := "127.0.0.1"

klbHostName := "klb." + testHostname
geo1KlbHostName := geoCode + "." + klbHostName
cluster1KlbHostName := "cluster1." + klbHostName

dnsRecord = &v1alpha1.DNSRecord{
ObjectMeta: metav1.ObjectMeta{
Name: "test-record",
Namespace: testNamespace,
},
Spec: v1alpha1.DNSRecordSpec{
ManagedZoneRef: &v1alpha1.ManagedZoneReference{
Name: testManagedZoneName,
},
Endpoints: []*externaldnsendpoint.Endpoint{
{
DNSName: cluster1KlbHostName,
Targets: []string{
testTargetIP,
},
RecordType: "A",
RecordTTL: 60,
},
{
DNSName: testHostname,
Targets: []string{
klbHostName,
},
RecordType: "CNAME",
RecordTTL: 300,
},
{
DNSName: geo1KlbHostName,
Targets: []string{
cluster1KlbHostName,
},
RecordType: "CNAME",
RecordTTL: 60,
SetIdentifier: cluster1KlbHostName,
ProviderSpecific: externaldnsendpoint.ProviderSpecific{
{
Name: "weight",
Value: "200",
},
},
},
{
DNSName: klbHostName,
Targets: []string{
geo1KlbHostName,
},
RecordType: "CNAME",
RecordTTL: 300,
SetIdentifier: geoCode,
ProviderSpecific: externaldnsendpoint.ProviderSpecific{
{
Name: "geo-code",
Value: geoCode,
},
},
},
{
DNSName: klbHostName,
Targets: []string{
geo1KlbHostName,
},
RecordType: "CNAME",
RecordTTL: 300,
SetIdentifier: "default",
ProviderSpecific: externaldnsendpoint.ProviderSpecific{
{
Name: "geo-code",
Value: "*",
},
},
},
},
},
}
err := k8sClient.Create(ctx, dnsRecord)
Expect(err).ToNot(HaveOccurred())

Eventually(func(g Gomega, ctx context.Context) {
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(dnsRecord), dnsRecord)
g.Expect(err).NotTo(HaveOccurred())
g.Expect(dnsRecord.Status.Conditions).To(
ContainElement(MatchFields(IgnoreExtras, Fields{
"Type": Equal(string(conditions.ConditionTypeReady)),
"Status": Equal(metav1.ConditionTrue),
})),
)
}, 300*time.Second, 10*time.Second, ctx).Should(Succeed())

By("ensuring the authoritative nameserver resolves the hostname")
// speed up things by using the authoritative nameserver
authoritativeResolver := ResolverForDomainName(testZoneDomainName)
Eventually(func(g Gomega, ctx context.Context) {
ips, err := authoritativeResolver.LookupHost(ctx, testHostname)
g.Expect(err).NotTo(HaveOccurred())
g.Expect(ips).To(ContainElement(testTargetIP))
}, 300*time.Second, 10*time.Second, ctx).Should(Succeed())
})
})

})
Loading

0 comments on commit ab616d0

Please sign in to comment.