test

package
v0.0.1-alpha.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2024 License: Apache-2.0 Imports: 38 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// TestNamespace is the namespace used for testing. Name reflects it represents a greenhouse org.
	TestNamespace = "test-org"
)

Variables

View Source
var (
	// Cfg is the rest.Config to access the cluster the tests are running against.
	Cfg *rest.Config
	// RestClientGetter is the clientutil.RestClientGetter to access the cluster the tests are running against.
	RestClientGetter *clientutil.RestClientGetter
	// K8sClient is the client.Client to access the cluster the tests are running against.
	K8sClient client.Client
	// K8sManager is the ctrl.Manager the controllers are run by.
	K8sManager ctrl.Manager
	// KubeConfig is the raw kubeconfig to access the cluster the tests are running against.
	KubeConfig []byte
	// Ctx is the context to use for the tests.
	Ctx context.Context
	// IsUseExistingCluster is true if the tests are running against an existing cluster.
	IsUseExistingCluster = useExistingGreenhouseCluster

	// TestBeforeSuite configures the test suite.
	TestBeforeSuite = func() {
		logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))

		SetDefaultEventuallyPollingInterval(1 * time.Second)
		SetDefaultEventuallyTimeout(1 * time.Minute)

		installCRDs := clientutil.GetEnvOrDefault("TEST_INSTALL_CRDS", "true") == "true"
		installWebhooks := len(allRegisterWebhookFuncs) > 0 && os.Getenv("TEST_INSTALL_WEBHOOKS") != "false"
		if useExistingGreenhouseCluster {

			e2eKubeconfig := os.Getenv("TEST_KUBECONFIG")
			Expect(e2eKubeconfig).NotTo(BeEmpty(), "the environment variable TEST_KUBECONFIG must be set to run the tests against a remote cluster")

			os.Setenv("KUBECONFIG", e2eKubeconfig)
			fmt.Printf("Running tests against existing cluster with kubeconfig: %s\n", e2eKubeconfig)
			installCRDs = false
			installWebhooks = false
		} else {

			_, isHasEnvKubebuilderAssets := os.LookupEnv("KUBEBUILDER_ASSETS")
			Expect(isHasEnvKubebuilderAssets).
				To(BeTrue(), "the environment variable KUBEBUILDER_ASSETS must be set to run the tests against local envtest")
		}

		Cfg, K8sClient, testEnv, KubeConfig = StartControlPlane("", installCRDs, installWebhooks)
		_ = K8sClient

		RestClientGetter = clientutil.NewRestClientGetterFromRestConfig(Cfg, TestNamespace, clientutil.WithPersistentConfig())
		Expect(RestClientGetter).ToNot(BeNil(), "the RestClientGetter should not be nil")

		Ctx, cancel = context.WithCancel(context.TODO())

		if !useExistingGreenhouseCluster {
			//+kubebuilder:scaffold:scheme
			var err error
			K8sManager, err = ctrl.NewManager(Cfg, ctrl.Options{
				Scheme: scheme.Scheme,
				Metrics: metricsserver.Options{
					BindAddress: "0",
				},
				WebhookServer: webhook.NewServer(webhook.Options{
					Host:    testEnv.WebhookInstallOptions.LocalServingHost,
					Port:    testEnv.WebhookInstallOptions.LocalServingPort,
					CertDir: testEnv.WebhookInstallOptions.LocalServingCertDir,
				}),
				LeaderElection: false,
			})
			Expect(err).
				ToNot(HaveOccurred(), "there must be no error creating a manager")
			Expect(K8sManager).
				NotTo(BeNil(), "the manager must not be nil")

			for webhookName, registerFunc := range allRegisterWebhookFuncs {
				logf.FromContext(Ctx, "message", "registering webhook", "name", webhookName)
				Expect(registerFunc(K8sManager)).To(Succeed(), "there must be no error registering the webhook", "name", webhookName)
			}

			for controllerName, registerFunc := range allRegisterControllerFuncs {
				Expect(registerFunc(controllerName, K8sManager)).
					To(Succeed(), "there must be no error registering the controller", "name", controllerName)
			}

			go func() {
				defer GinkgoRecover()
				err = K8sManager.Start(Ctx)
				Expect(err).
					ToNot(HaveOccurred(), "there must be no error starting the manager")
			}()

			if len(allRegisterWebhookFuncs) > 0 {

				dialer := &net.Dialer{Timeout: time.Second}
				addrPort := fmt.Sprintf("%s:%d", testEnv.WebhookInstallOptions.LocalServingHost, testEnv.WebhookInstallOptions.LocalServingPort)
				Eventually(func() error {
					conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true})
					if err != nil {
						return err
					}
					conn.Close()
					return nil
				}, updateTimeout, pollInterval).Should(Succeed(), "there should be no error dialing the webhook server")
			}
		}

		err := K8sClient.Create(Ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: TestNamespace}})
		Expect(err).NotTo(HaveOccurred(), "there should be no error creating the test namespace")
	}

	// TestAfterSuite configures the test suite.
	TestAfterSuite = func() {

		err := K8sClient.Delete(Ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: TestNamespace}})
		Expect(err).NotTo(HaveOccurred(), "there should be no error deleting the test namespace")
		cancel()
		By("tearing down the test environment")
		Eventually(func() error {
			return testEnv.Stop()
		}).Should(Succeed(), "there should be no error stopping the test environment")

		if useExistingGreenhouseCluster {

			os.Setenv("KUBECONFIG", persistedKubeconfig)
		}
	}
)
View Source
var ClientObjectMatcherByName = func(name string) gomegaTypes.GomegaMatcher {
	return gstruct.MatchFields(
		gstruct.IgnoreExtras, gstruct.Fields{"ObjectMeta": gstruct.MatchFields(
			gstruct.IgnoreExtras, gstruct.Fields{"Name": Equal(
				name)})})
}

Functions

func DummyTailscaleClientGetter

func DummyTailscaleClientGetter(restClientGetter genericclioptions.RESTClientGetter, proxy, headscaleAddress string) (client.Client, error)

DummyTailscaleClienGetter is a dummy tailscale client getter for testing purposes. As we do not have a headscale setup for testing, we need to mock the tailscale client getter.

func EventuallyCreated

func EventuallyCreated(ctx context.Context, c client.Client, obj client.Object)

EventuallyGet gets the object and retries until it is available.

func EventuallyDeleted

func EventuallyDeleted(ctx context.Context, c client.Client, obj client.Object)

EventuallyDeleted deletes the object and waits until it is gone. Early return if the delete fails with NotFound

func GreenhouseV1Alpha1Scheme

func GreenhouseV1Alpha1Scheme() *runtime.Scheme

GreenhouseV1Alpha1Scheme returns a new runtime.Scheme with the Greenhouse v1alpha1 scheme added.

func KubeconfigFromEnvVar

func KubeconfigFromEnvVar(envVar string) ([]byte, error)

KubeconfigFromEnvVar returns the kubeconfig []byte from the path specified in the environment variable

func MustDeleteCluster

func MustDeleteCluster(ctx context.Context, c client.Client, id client.ObjectKey)

MustDeleteCluster is used in the test context only and removes a cluster by namespaced name.

func MustReturnJSONFor

func MustReturnJSONFor(val any) *apiextensionsv1.JSON

MustReturnJSONFor marshals val to JSON and returns an apiextensionsv1.JSON.

func RegisterController

func RegisterController(controllerName string, f registerControllerFunc)

RegisterController registers a controller for the testbed. A currently running testbed is not affected.

func RegisterWebhook

func RegisterWebhook(webhookName string, f registerWebhookFunc)

RegisterWebhook registers a webhook for the testbed. A currently running testbed is not affected.

func StartControlPlane

func StartControlPlane(port string, installCRDs, installWebhooks bool) (*rest.Config, client.Client, *envtest.Environment, []byte)

Starts a envTest control plane and returns the config, client, envtest.Environment and raw kubeconfig.

func UnregisterController

func UnregisterController(controllerName string)

UnregisterController removes a controller from the testbed. A currently running testbed is not affected.

func UnregisterWebhook

func UnregisterWebhook(webhookName string)

UnregisterWebhook removes a webhook from the testbed. A currently running testbed is not affected.

func WithAccessMode

WithAccessMode sets the ClusterAccessMode on a Cluster

func WithAggregationRule

func WithAggregationRule(aggregationRule *rbacv1.AggregationRule) func(*greenhousev1alpha1.TeamRole)

WithAggregationRule sets the AggregationRule on a TeamRole

func WithClusterName

func WithClusterName(clusterName string) func(*greenhousev1alpha1.TeamRoleBinding)

func WithClusterSelector

func WithClusterSelector(selector metav1.LabelSelector) func(*greenhousev1alpha1.TeamRoleBinding)

func WithLabel

func WithLabel(key, value string) func(*greenhousev1alpha1.Cluster)

WithLabel sets the label on a Cluster

func WithLabels

func WithLabels(labels map[string]string) func(*greenhousev1alpha1.TeamRole)

WithLabels sets the .spec.Labels on a TeamRole

func WithMappedIDPGroup

func WithMappedIDPGroup(group string) func(*greenhousev1alpha1.Team)

func WithNamespaces

func WithNamespaces(namespaces ...string) func(*greenhousev1alpha1.TeamRoleBinding)

func WithRules

func WithRules(rules []rbacv1.PolicyRule) func(*greenhousev1alpha1.TeamRole)

WithRules overrides the default rules of a TeamRole

func WithSecretData

func WithSecretData(data map[string][]byte) func(*corev1.Secret)

WithSecretData sets the data of the Secret

func WithSecretType

func WithSecretType(secretType corev1.SecretType) func(*corev1.Secret)

WithSecretType sets the type of the Secret

func WithTeamRef

func WithTeamRef(teamRef string) func(*greenhousev1alpha1.TeamRoleBinding)

func WithTeamRoleRef

func WithTeamRoleRef(roleRef string) func(*greenhousev1alpha1.TeamRoleBinding)

Types

type FakeHeadscaleClient

type FakeHeadscaleClient struct {
	// IsUserDeleted is used to simulate the deletion of a user. If set to true, the GetUserFunc will return an error.
	IsUserDeleted bool

	CreateApiKeyFunc       func(context.Context, *v1.CreateApiKeyRequest, ...grpc.CallOption) (*v1.CreateApiKeyResponse, error) // no-lint:stylecheck
	CreatePreAuthKeyFunc   func(context.Context, *v1.CreatePreAuthKeyRequest, ...grpc.CallOption) (*v1.CreatePreAuthKeyResponse, error)
	CreateUserFunc         func(context.Context, *v1.CreateUserRequest, ...grpc.CallOption) (*v1.CreateUserResponse, error)
	DebugCreateMachineFunc func(context.Context, *v1.DebugCreateMachineRequest, ...grpc.CallOption) (*v1.DebugCreateMachineResponse, error)
	DeleteMachineFunc      func(context.Context, *v1.DeleteMachineRequest, ...grpc.CallOption) (*v1.DeleteMachineResponse, error)
	DeleteRouteFunc        func(context.Context, *v1.DeleteRouteRequest, ...grpc.CallOption) (*v1.DeleteRouteResponse, error)
	DeleteUserFunc         func(context.Context, *v1.DeleteUserRequest, ...grpc.CallOption) (*v1.DeleteUserResponse, error)
	DisableRouteFunc       func(context.Context, *v1.DisableRouteRequest, ...grpc.CallOption) (*v1.DisableRouteResponse, error)
	EnableRouteFunc        func(context.Context, *v1.EnableRouteRequest, ...grpc.CallOption) (*v1.EnableRouteResponse, error)
	ExpireApiKeyFunc       func(context.Context, *v1.ExpireApiKeyRequest, ...grpc.CallOption) (*v1.ExpireApiKeyResponse, error) // no-lint:stylecheck
	ExpireMachineFunc      func(context.Context, *v1.ExpireMachineRequest, ...grpc.CallOption) (*v1.ExpireMachineResponse, error)
	ExpirePreAuthKeyFunc   func(context.Context, *v1.ExpirePreAuthKeyRequest, ...grpc.CallOption) (*v1.ExpirePreAuthKeyResponse, error)
	GetMachineFunc         func(context.Context, *v1.GetMachineRequest, ...grpc.CallOption) (*v1.GetMachineResponse, error)
	GetMachineRoutesFunc   func(context.Context, *v1.GetMachineRoutesRequest, ...grpc.CallOption) (*v1.GetMachineRoutesResponse, error)
	GetRoutesFunc          func(context.Context, *v1.GetRoutesRequest, ...grpc.CallOption) (*v1.GetRoutesResponse, error)
	GetUserFunc            func(context.Context, *v1.GetUserRequest, ...grpc.CallOption) (*v1.GetUserResponse, error)
	ListApiKeysFunc        func(context.Context, *v1.ListApiKeysRequest, ...grpc.CallOption) (*v1.ListApiKeysResponse, error)
	ListMachinesFunc       func(context.Context, *v1.ListMachinesRequest, ...grpc.CallOption) (*v1.ListMachinesResponse, error)
	ListPreAuthKeysFunc    func(context.Context, *v1.ListPreAuthKeysRequest, ...grpc.CallOption) (*v1.ListPreAuthKeysResponse, error)
	ListUsersFunc          func(context.Context, *v1.ListUsersRequest, ...grpc.CallOption) (*v1.ListUsersResponse, error)
	MoveMachineFunc        func(context.Context, *v1.MoveMachineRequest, ...grpc.CallOption) (*v1.MoveMachineResponse, error)
	RegisterMachineFunc    func(context.Context, *v1.RegisterMachineRequest, ...grpc.CallOption) (*v1.RegisterMachineResponse, error)
	RenameMachineFunc      func(context.Context, *v1.RenameMachineRequest, ...grpc.CallOption) (*v1.RenameMachineResponse, error)
	RenameUserFunc         func(context.Context, *v1.RenameUserRequest, ...grpc.CallOption) (*v1.RenameUserResponse, error)
	SetTagsFunc            func(context.Context, *v1.SetTagsRequest, ...grpc.CallOption) (*v1.SetTagsResponse, error)
}

FakeHeadscaleClient is a fake implementation of the HeadscaleClient interface.

func (FakeHeadscaleClient) CreateApiKey

func (FakeHeadscaleClient) CreatePreAuthKey

func (FakeHeadscaleClient) CreateUser

func (FakeHeadscaleClient) DebugCreateMachine

func (FakeHeadscaleClient) DeleteMachine

func (FakeHeadscaleClient) DeleteRoute

func (FakeHeadscaleClient) DeleteUser

func (FakeHeadscaleClient) DisableRoute

func (FakeHeadscaleClient) EnableRoute

func (FakeHeadscaleClient) ExpireApiKey

func (FakeHeadscaleClient) ExpireMachine

func (FakeHeadscaleClient) ExpirePreAuthKey

func (FakeHeadscaleClient) GetMachine

func (FakeHeadscaleClient) GetMachineRoutes

func (FakeHeadscaleClient) GetRoutes

func (FakeHeadscaleClient) GetUser

func (FakeHeadscaleClient) ListApiKeys

func (FakeHeadscaleClient) ListMachines

func (FakeHeadscaleClient) ListPreAuthKeys

func (FakeHeadscaleClient) ListUsers

func (FakeHeadscaleClient) MoveMachine

func (FakeHeadscaleClient) RegisterMachine

func (FakeHeadscaleClient) RenameMachine

func (FakeHeadscaleClient) RenameUser

func (FakeHeadscaleClient) SetTags

type TestSetup

type TestSetup struct {
	client.Client
	// contains filtered or unexported fields
}

func NewTestSetup

func NewTestSetup(ctx context.Context, c client.Client, name string) *TestSetup

NewTestSetup creates a new TestSetup object and a new namespace on the cluster for the test

func (*TestSetup) CreateCluster

func (t *TestSetup) CreateCluster(ctx context.Context, name string, opts ...func(*greenhousev1alpha1.Cluster)) *greenhousev1alpha1.Cluster

CreateCluster creates a new Cluster resource without creating a Secret

func (*TestSetup) CreateOrganization

func (t *TestSetup) CreateOrganization(ctx context.Context, name string) *greenhousev1alpha1.Organization

CreateOrganization creates a Organization within the TestSetup and returns the created Organization resource.

func (*TestSetup) CreateSecret

func (t *TestSetup) CreateSecret(ctx context.Context, name string, opts ...func(*corev1.Secret)) *corev1.Secret

CreateSecret returns a Secret object. Opts can be used to set the desired state of the Secret.

func (*TestSetup) CreateTeam

func (t *TestSetup) CreateTeam(ctx context.Context, name string, opts ...func(*greenhousev1alpha1.Team)) *greenhousev1alpha1.Team

CreateTeam returns a Team object. Opts can be used to set the desired state of the Team.st

func (*TestSetup) CreateTeamRole

func (t *TestSetup) CreateTeamRole(ctx context.Context, name string, opts ...func(*greenhousev1alpha1.TeamRole)) *greenhousev1alpha1.TeamRole

CreateTeamRole returns a TeamRole object. Opts can be used to set the desired state of the TeamRole.

func (*TestSetup) CreateTeamRoleBinding

func (t *TestSetup) CreateTeamRoleBinding(ctx context.Context, name string, opts ...func(*greenhousev1alpha1.TeamRoleBinding)) *greenhousev1alpha1.TeamRoleBinding

CreateTeamRoleBinding returns a TeamRoleBinding object. Opts can be used to set the desired state of the TeamRoleBinding.

func (*TestSetup) Namespace

func (t *TestSetup) Namespace() string

func (*TestSetup) NewTeamRole

func (t *TestSetup) NewTeamRole(ctx context.Context, name string, opts ...func(*greenhousev1alpha1.TeamRole)) *greenhousev1alpha1.TeamRole

func (*TestSetup) OnboardCluster

func (t *TestSetup) OnboardCluster(ctx context.Context, name string, kubeCfg []byte, opts ...func(*greenhousev1alpha1.Cluster)) *greenhousev1alpha1.Cluster

OnboardCluster creates a new Cluster and Kubernetes secret for a remote cluster and creates the namespace used for TestSetup on the remote cluster

func (*TestSetup) RandomizeName

func (t *TestSetup) RandomizeName(name string) string

RandomizeName returns the name with a random alphanumeric suffix

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL