Skip to content

test: scaffold e2e tests #189

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

Merged
merged 2 commits into from
Dec 10, 2024
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
9 changes: 9 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ issues:
# don't skip warning about doc comments
# don't exclude the default set of lint
exclude-use-default: false
# restore some of the defaults
# (fill in the rest as needed)
exclude-dirs:
- tests
exclude-files:
- ".*_test\\.go"

Expand All @@ -32,3 +36,8 @@ linters:
- unconvert
- unparam
- unused

linters-settings:
revive:
rules:
- name: comment-spacings
6 changes: 3 additions & 3 deletions api/v1alpha1/maasvalidator_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ type Resource struct {
// MaasValidatorStatus defines the observed state of MaasValidator
type MaasValidatorStatus struct{}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status

// MaasValidator is the Schema for the maasvalidators API
type MaasValidator struct {
Expand All @@ -219,7 +219,7 @@ func (v MaasValidator) ResultCount() int {
return v.Spec.ResultCount()
}

//+kubebuilder:object:root=true
// +kubebuilder:object:root=true

// MaasValidatorList contains a list of MaasValidator
type MaasValidatorList struct {
Expand Down
28 changes: 16 additions & 12 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2023.
Copyright 2024.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -14,7 +14,6 @@
limitations under the License.
*/

// Package main initializes a MaasValidator controller.
package main

import (
Expand All @@ -34,11 +33,11 @@
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"sigs.k8s.io/controller-runtime/pkg/metrics/filters"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
"sigs.k8s.io/controller-runtime/pkg/webhook"

validationv1alpha1 "github.com/validator-labs/validator-plugin-maas/api/v1alpha1"
"github.com/validator-labs/validator-plugin-maas/internal/controller"
validatorv1alpha1 "github.com/validator-labs/validator/api/v1alpha1"
//+kubebuilder:scaffold:imports
// +kubebuilder:scaffold:imports
)

var (
Expand All @@ -48,9 +47,9 @@

func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
utilruntime.Must(validatorv1alpha1.AddToScheme(scheme))

Check warning on line 50 in cmd/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/main.go#L50

Added line #L50 was not covered by tests
utilruntime.Must(validationv1alpha1.AddToScheme(scheme))
//+kubebuilder:scaffold:scheme
// +kubebuilder:scaffold:scheme

Check warning on line 52 in cmd/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/main.go#L52

Added line #L52 was not covered by tests
}

func main() {
Expand All @@ -60,17 +59,16 @@
var secureMetrics bool
var enableHTTP2 bool
var tlsOpts []func(*tls.Config)
flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
"Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")

Check warning on line 63 in cmd/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/main.go#L62-L63

Added lines #L62 - L63 were not covered by tests
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
"Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
"Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")
flag.BoolVar(&secureMetrics, "metrics-secure", true,
"If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.")
flag.BoolVar(&enableHTTP2, "enable-http2", false,
"If set, HTTP/2 will be enabled for the metrics and webhook servers")

opts := zap.Options{
Development: true,
}
Expand All @@ -93,6 +91,11 @@
if !enableHTTP2 {
tlsOpts = append(tlsOpts, disableHTTP2)
}

webhookServer := webhook.NewServer(webhook.Options{
TLSOpts: tlsOpts,
})

Check warning on line 98 in cmd/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/main.go#L95-L98

Added lines #L95 - L98 were not covered by tests
// Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server.
// More info:
// - https://pkg.go.dev/sigs.k8s.io/[email protected]/pkg/metrics/server
Expand All @@ -116,18 +119,19 @@

// TODO(user): If cert-manager is enabled in config/default/kustomization.yaml,
// you can uncomment the following lines to use the certificate managed by cert-manager.

Check warning on line 122 in cmd/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/main.go#L122

Added line #L122 was not covered by tests
// metricsServerOptions.CertDir = "/tmp/k8s-metrics-server/metrics-certs"
// metricsServerOptions.CertName = "tls.crt"
// metricsServerOptions.KeyName = "tls.key"

}

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
Metrics: metricsServerOptions,
WebhookServer: webhookServer,

Check warning on line 131 in cmd/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/main.go#L131

Added line #L131 was not covered by tests
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "ecaf1259.spectrocloud.labs",
LeaderElectionID: "dee7189b.spectrocloud.labs",

Check warning on line 134 in cmd/main.go

View check run for this annotation

Codecov / codecov/patch

cmd/main.go#L134

Added line #L134 was not covered by tests
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
// when the Manager ends. This requires the binary to immediately end when the
// Manager is stopped, otherwise, this setting is unsafe. Setting this significantly
Expand All @@ -153,7 +157,7 @@
setupLog.Error(err, "unable to create controller", "controller", "MaasValidator")
os.Exit(1)
}
//+kubebuilder:scaffold:builder
// +kubebuilder:scaffold:builder

if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
setupLog.Error(err, "unable to set up health check")
Expand Down
10 changes: 0 additions & 10 deletions config/default/manager_config_patch.yaml

This file was deleted.

17 changes: 17 additions & 0 deletions config/default/metrics_service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
labels:
control-plane: controller-manager
app.kubernetes.io/name: validator-plugin-maas
app.kubernetes.io/managed-by: kustomize
name: controller-manager-metrics-service
namespace: system
spec:
ports:
- name: https
port: 8443
protocol: TCP
targetPort: 8443
selector:
control-plane: controller-manager
1 change: 1 addition & 0 deletions config/manager/manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ spec:
- --leader-elect
- --health-probe-bind-address=:8081
image: controller:latest
imagePullPolicy: IfNotPresent
name: manager
securityContext:
allowPrivilegeEscalation: false
Expand Down
26 changes: 26 additions & 0 deletions config/network-policy/allow-metrics-traffic.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# This NetworkPolicy allows ingress traffic
# with Pods running on namespaces labeled with 'metrics: enabled'. Only Pods on those
# namespaces are able to gathering data from the metrics endpoint.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
app.kubernetes.io/name: validator-plugin-maas
app.kubernetes.io/managed-by: kustomize
name: allow-metrics-traffic
namespace: system
spec:
podSelector:
matchLabels:
control-plane: controller-manager
policyTypes:
- Ingress
ingress:
# This allows ingress traffic from any namespace with the label metrics: enabled
- from:
- namespaceSelector:
matchLabels:
metrics: enabled # Only from namespaces with this label
ports:
- port: 8443
protocol: TCP
2 changes: 2 additions & 0 deletions config/network-policy/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
resources:
- allow-metrics-traffic.yaml
4 changes: 4 additions & 0 deletions config/samples/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## Append samples of your project ##
resources:
- validation_v1alpha1_maasvalidator.yaml
# +kubebuilder:scaffold:manifestskustomizesamples
6 changes: 3 additions & 3 deletions internal/controller/maasvalidator_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ type MaasValidatorReconciler struct {
Scheme *runtime.Scheme
}

//+kubebuilder:rbac:groups=validation.spectrocloud.labs,resources=maasvalidators,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=validation.spectrocloud.labs,resources=maasvalidators/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=validation.spectrocloud.labs,resources=maasvalidators/finalizers,verbs=update
// +kubebuilder:rbac:groups=validation.spectrocloud.labs,resources=maasvalidators,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=validation.spectrocloud.labs,resources=maasvalidators/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=validation.spectrocloud.labs,resources=maasvalidators/finalizers,verbs=update

// Reconcile reconciles each rule found in each MaasValidator in the cluster and creates ValidationResults accordingly
func (r *MaasValidatorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
Expand Down
2 changes: 1 addition & 1 deletion internal/controller/maasvalidator_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"k8s.io/apimachinery/pkg/types"

// . "github.com/onsi/gomega"
//+kubebuilder:scaffold:imports
// +kubebuilder:scaffold:imports
"github.com/validator-labs/validator-plugin-maas/api/v1alpha1"
"github.com/validator-labs/validator-plugin-maas/pkg/validate"
vapi "github.com/validator-labs/validator/api/v1alpha1"
Expand Down
4 changes: 2 additions & 2 deletions internal/controller/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import (
v1alpha1 "github.com/validator-labs/validator-plugin-maas/api/v1alpha1"
vapi "github.com/validator-labs/validator/api/v1alpha1"
"github.com/validator-labs/validator/pkg/util"
//+kubebuilder:scaffold:imports
// +kubebuilder:scaffold:imports
)

// These tests use Ginkgo (BDD-style Go testing framework). Refer to
Expand Down Expand Up @@ -115,7 +115,7 @@ var _ = BeforeSuite(func() {
err = vapi.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())

//+kubebuilder:scaffold:scheme
// +kubebuilder:scaffold:scheme

k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
Expect(err).NotTo(HaveOccurred())
Expand Down
120 changes: 120 additions & 0 deletions tests/e2e/e2e_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
Copyright 2024.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package e2e

import (
"fmt"
"os"
"os/exec"
"testing"

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

"github.com/validator-labs/validator-plugin-maas/tests/utils"
)

var (
// Optional Environment Variables:
// - PROMETHEUS_INSTALL_SKIP=true: Skips Prometheus Operator installation during test setup.
// - CERT_MANAGER_INSTALL_SKIP=true: Skips CertManager installation during test setup.
// These variables are useful if Prometheus or CertManager is already installed, avoiding
// re-installation and conflicts.
skipPrometheusInstall = os.Getenv("PROMETHEUS_INSTALL_SKIP") == "true"
skipCertManagerInstall = os.Getenv("CERT_MANAGER_INSTALL_SKIP") == "true"
// isPrometheusOperatorAlreadyInstalled will be set true when prometheus CRDs be found on the cluster
isPrometheusOperatorAlreadyInstalled = false
// isCertManagerAlreadyInstalled will be set true when CertManager CRDs be found on the cluster
isCertManagerAlreadyInstalled = false

// projectImage is the name of the image which will be build and loaded
// with the code source changes to be tested.
projectImage = "quay.io/validator-labs/validator-plugin-maas:latest"
)

// TestE2E runs the end-to-end (e2e) test suite for the project. These tests execute in an isolated,
// temporary environment to validate project changes with the the purposed to be used in CI jobs.
// The default setup requires Kind, builds/loads the Manager Docker image locally, and installs
// CertManager and Prometheus.
func TestE2E(t *testing.T) {
RegisterFailHandler(Fail)
_, _ = fmt.Fprintf(GinkgoWriter, "Starting validator-plugin-maas integration test suite\n")
RunSpecs(t, "e2e suite")
}

var _ = BeforeSuite(func() {
By("Ensure that Prometheus is enabled")
_ = utils.UncommentCode("config/default/kustomization.yaml", "#- ../prometheus", "#")

By("generating files")
cmd := exec.Command("make", "generate")
_, err := utils.Run(cmd)
ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to run make generate")

By("generating manifests")
cmd = exec.Command("make", "manifests")
_, err = utils.Run(cmd)
ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to run make manifests")

By("building the manager(Operator) image")
cmd = exec.Command("make", "docker-build", fmt.Sprintf("IMG=%s", projectImage))
_, err = utils.Run(cmd)
ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to build the manager(Operator) image")

// TODO(user): If you want to change the e2e test vendor from Kind, ensure the image is
// built and available before running the tests. Also, remove the following block.
By("loading the manager(Operator) image on Kind")
err = utils.LoadImageToKindClusterWithName(projectImage)
ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to load the manager(Operator) image into Kind")

// The tests-e2e are intended to run on a temporary cluster that is created and destroyed for testing.
// To prevent errors when tests run in environments with Prometheus or CertManager already installed,
// we check for their presence before execution.
// Setup Prometheus and CertManager before the suite if not skipped and if not already installed
if !skipPrometheusInstall {
By("checking if prometheus is installed already")
isPrometheusOperatorAlreadyInstalled = utils.IsPrometheusCRDsInstalled()
if !isPrometheusOperatorAlreadyInstalled {
_, _ = fmt.Fprintf(GinkgoWriter, "Installing Prometheus Operator...\n")
Expect(utils.InstallPrometheusOperator()).To(Succeed(), "Failed to install Prometheus Operator")
} else {
_, _ = fmt.Fprintf(GinkgoWriter, "WARNING: Prometheus Operator is already installed. Skipping installation...\n")
}
}
if !skipCertManagerInstall {
By("checking if cert manager is installed already")
isCertManagerAlreadyInstalled = utils.IsCertManagerCRDsInstalled()
if !isCertManagerAlreadyInstalled {
_, _ = fmt.Fprintf(GinkgoWriter, "Installing CertManager...\n")
Expect(utils.InstallCertManager()).To(Succeed(), "Failed to install CertManager")
} else {
_, _ = fmt.Fprintf(GinkgoWriter, "WARNING: CertManager is already installed. Skipping installation...\n")
}
}
})

var _ = AfterSuite(func() {
// Teardown Prometheus and CertManager after the suite if not skipped and if they were not already installed
if !skipPrometheusInstall && !isPrometheusOperatorAlreadyInstalled {
_, _ = fmt.Fprintf(GinkgoWriter, "Uninstalling Prometheus Operator...\n")
utils.UninstallPrometheusOperator()
}
if !skipCertManagerInstall && !isCertManagerAlreadyInstalled {
_, _ = fmt.Fprintf(GinkgoWriter, "Uninstalling CertManager...\n")
utils.UninstallCertManager()
}
})
Loading
Loading