Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests: migrate GatewayClass related integration tests to envtest based tests #4172

Merged
merged 11 commits into from
Jun 20, 2023
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
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package gateway
package controllers

import (
"context"

"github.com/kong/go-kong/kong"
"sigs.k8s.io/controller-runtime/pkg/client"

k8sobj "github.com/kong/kubernetes-ingress-controller/v2/internal/util/kubernetes/object"
Expand All @@ -14,6 +17,7 @@ import (
type DataPlane interface {
DataPlaneClient

Listeners(ctx context.Context) ([]kong.ProxyListener, []kong.StreamListener, error)
AreKubernetesObjectReportsEnabled() bool
KubernetesObjectConfigurationStatus(obj client.Object) k8sobj.ConfigurationStatus
}
Expand Down
9 changes: 7 additions & 2 deletions internal/controllers/gateway/gateway_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ import (
gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"

"github.com/kong/kubernetes-ingress-controller/v2/internal/annotations"
"github.com/kong/kubernetes-ingress-controller/v2/internal/controllers"
ctrlref "github.com/kong/kubernetes-ingress-controller/v2/internal/controllers/reference"
ctrlutils "github.com/kong/kubernetes-ingress-controller/v2/internal/controllers/utils"
"github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane"
"github.com/kong/kubernetes-ingress-controller/v2/internal/util"
)

Expand All @@ -53,7 +53,7 @@ type GatewayReconciler struct { //nolint:revive

Log logr.Logger
Scheme *runtime.Scheme
DataplaneClient *dataplane.KongClient
DataplaneClient controllers.DataPlane

WatchNamespaces []string
CacheSyncTimeout time.Duration
Expand Down Expand Up @@ -161,6 +161,11 @@ func (r *GatewayReconciler) SetupWithManager(mgr ctrl.Manager) error {
return gwcCTRL.SetupWithManager(mgr)
}

// SetLogger sets the logger.
func (r *GatewayReconciler) SetLogger(l logr.Logger) {
r.Log = l
}

// -----------------------------------------------------------------------------
// Gateway Controller - Watch Predicates
// -----------------------------------------------------------------------------
Expand Down
5 changes: 5 additions & 0 deletions internal/controllers/gateway/gatewayclass_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ func (r *GatewayClassReconciler) Reconcile(ctx context.Context, req ctrl.Request
return ctrl.Result{}, nil
}

// SetLogger sets the logger.
func (r *GatewayClassReconciler) SetLogger(l logr.Logger) {
r.Log = l
}

// -----------------------------------------------------------------------------
// GatewayClass Controller - Private
// -----------------------------------------------------------------------------
Expand Down
3 changes: 2 additions & 1 deletion internal/controllers/gateway/httproute_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/source"
gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"

"github.com/kong/kubernetes-ingress-controller/v2/internal/controllers"
ctrlutils "github.com/kong/kubernetes-ingress-controller/v2/internal/controllers/utils"
"github.com/kong/kubernetes-ingress-controller/v2/internal/util"
k8sobj "github.com/kong/kubernetes-ingress-controller/v2/internal/util/kubernetes/object"
Expand All @@ -39,7 +40,7 @@ type HTTPRouteReconciler struct {

Log logr.Logger
Scheme *runtime.Scheme
DataplaneClient DataPlane
DataplaneClient controllers.DataPlane
CacheSyncTimeout time.Duration

// If enableReferenceGrant is true, we will check for ReferenceGrant if backend in another
Expand Down
4 changes: 2 additions & 2 deletions internal/controllers/reference/indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"k8s.io/client-go/tools/cache"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane"
"github.com/kong/kubernetes-ingress-controller/v2/internal/controllers"
)

const (
Expand Down Expand Up @@ -155,7 +155,7 @@ func (c CacheIndexers) DeleteReferencesByReferrer(referrer client.Object) error

// DeleteObjectIfNotReferred deletes object from object cach by dataplaneClient
// the object is not referenced in reference cache.
func (c CacheIndexers) DeleteObjectIfNotReferred(obj client.Object, dataplaneClient *dataplane.KongClient) error {
func (c CacheIndexers) DeleteObjectIfNotReferred(obj client.Object, dataplaneClient controllers.DataPlaneClient) error {
referred, err := c.ObjectReferred(obj)
if err != nil {
return err
Expand Down
8 changes: 4 additions & 4 deletions internal/controllers/reference/reference.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
k8stypes "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane"
"github.com/kong/kubernetes-ingress-controller/v2/internal/controllers"
)

const (
Expand All @@ -22,7 +22,7 @@ const (
// in namespacedNames in record cache.
func UpdateReferencesToSecret(
ctx context.Context,
c client.Client, indexers CacheIndexers, dataplaneClient *dataplane.KongClient,
c client.Client, indexers CacheIndexers, dataplaneClient controllers.DataPlaneClient,
referrer client.Object, referencedSecretNameMap map[k8stypes.NamespacedName]struct{},
) error {
for nsName := range referencedSecretNameMap {
Expand Down Expand Up @@ -60,7 +60,7 @@ func UpdateReferencesToSecret(
// and should be removed from the object cache inside KongClient.
func removeOutdatedReferencesToSecret(
ctx context.Context,
indexers CacheIndexers, c client.Client, dataplaneClient *dataplane.KongClient,
indexers CacheIndexers, c client.Client, dataplaneClient controllers.DataPlaneClient,
referrer client.Object, referredSecretNameMap map[k8stypes.NamespacedName]struct{},
) error {
referents, err := indexers.ListReferredObjects(referrer)
Expand Down Expand Up @@ -114,7 +114,7 @@ func removeOutdatedReferencesToSecret(
// DeleteReferencesByReferrer deletes all reference records with specified referrer
// in reference cache.
// If the affected secret is not referred by any other objects, it deletes the secret in object cache.
func DeleteReferencesByReferrer(indexers CacheIndexers, dataplaneClient *dataplane.KongClient, referrer client.Object) error {
func DeleteReferencesByReferrer(indexers CacheIndexers, dataplaneClient controllers.DataPlaneClient, referrer client.Object) error {
referents, err := indexers.ListReferredObjects(referrer)
if err != nil {
return err
Expand Down
65 changes: 65 additions & 0 deletions internal/util/builder/serviceport.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package builder

import (
"github.com/samber/lo"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/intstr"
)

// ServicePortBuilder is a builder for core v1 ServicePort.
// Primarily used for testing.
type ServicePortBuilder struct {
sp corev1.ServicePort
}

func NewServicePort() *ServicePortBuilder {
return &ServicePortBuilder{
sp: corev1.ServicePort{},
}
}

// WithNodePort sets the target port on the service port.
func (b *ServicePortBuilder) WithNodePort(port int32) *ServicePortBuilder {
b.sp.NodePort = port
return b
}

// WithTargetPort sets the target port on the service port.
func (b *ServicePortBuilder) WithTargetPort(targetport intstr.IntOrString) *ServicePortBuilder {
b.sp.TargetPort = targetport
return b
}

// WithPort sets the port on the service port.
func (b *ServicePortBuilder) WithPort(port int32) *ServicePortBuilder {
b.sp.Port = port
return b
}

// WithAppProtocol sets the app protocol on the service port.
func (b *ServicePortBuilder) WithAppProtocol(appproto string) *ServicePortBuilder {
b.sp.AppProtocol = lo.ToPtr(appproto)
return b
}

// WithProtocol sets the protocol on the service port.
func (b *ServicePortBuilder) WithProtocol(proto corev1.Protocol) *ServicePortBuilder {
b.sp.Protocol = proto
return b
}

// WithName sets the name on the service port.
func (b *ServicePortBuilder) WithName(name string) *ServicePortBuilder {
b.sp.Name = name
return b
}

// Build returns the configured ServicePort.
func (b *ServicePortBuilder) Build() corev1.ServicePort {
return b.sp
}

// IntoSlice returns the configured ServicePort in a slice.
func (b *ServicePortBuilder) IntoSlice() []corev1.ServicePort {
return []corev1.ServicePort{b.sp}
}
27 changes: 20 additions & 7 deletions test/envtest/controller.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package envtest

import (
"bytes"
"context"
"sync"
"testing"
Expand All @@ -17,23 +18,29 @@ import (
"github.com/kong/kubernetes-ingress-controller/v2/internal/controllers"
)

// StartReconciler creates a controller manager and starts the provided reconciler
// StartReconcilers creates a controller manager and starts the provided reconciler
// as its runnable.
// It also adds a t.Cleanup which waits for the maanger to exit so that the test
// can be self contained and logs from different tests' managers don't mix up.
func StartReconciler(ctx context.Context, t *testing.T, scheme *runtime.Scheme, cfg *rest.Config, reconciler controllers.Reconciler) {
func StartReconcilers(ctx context.Context, t *testing.T, scheme *runtime.Scheme, cfg *rest.Config, reconcilers ...controllers.Reconciler) {
t.Helper()

var b bytes.Buffer
log := logrus.New()
log.Out = &b
o := manager.Options{
Logger: logrusr.New(logrus.New()),
Logger: logrusr.New(log),
Scheme: scheme,
MetricsBindAddress: "0",
}

mgr, err := ctrl.NewManager(cfg, o)
require.NoError(t, err)

reconciler.SetLogger(mgr.GetLogger())

require.NoError(t, reconciler.SetupWithManager(mgr))
for _, r := range reconcilers {
r.SetLogger(mgr.GetLogger())
require.NoError(t, r.SetupWithManager(mgr))
}

// This wait group makes it so that we wait for manager to exit.
// This way we get clean test logs not mixing between tests.
Expand All @@ -43,5 +50,11 @@ func StartReconciler(ctx context.Context, t *testing.T, scheme *runtime.Scheme,
defer wg.Done()
assert.NoError(t, mgr.Start(ctx))
}()
t.Cleanup(func() { wg.Wait() })
t.Cleanup(func() {
wg.Wait()

if t.Failed() {
t.Logf("Test %s failed: dumping controller logs\n%s", t.Name(), b.String())
}
})
}
Loading