func ValidateBucketAccess(bucketaccess types.BucketAccess, bucketaccessrequest types.BucketAccessRequest, bucketaccessclass types.BucketAccessClass) bool {
	if bucketaccess.Spec.BucketName != "" &&
		bucketaccessrequest.Status.BucketAccessName == bucketaccess.Name &&
		bucketaccess.Spec.BucketAccessRequest.UID == bucketaccessrequest.UID &&
		bucketaccess.Spec.ServiceAccount.Name == bucketaccessrequest.Spec.ServiceAccountName &&
		bucketaccess.Spec.PolicyActionsConfigMapData != "" {
		return true
	}
	return false
}
Validates the content of the bucket access against bucket access request and backet access class
This is used by bucket access request unit tests
package util
import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"golang.org/x/time/rate"
	"os"
	"reflect"
	"strings"
	"time"
	v1 "k8s.io/api/core/v1"
	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
	apiextensions "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/uuid"
	kubeclientset "k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/workqueue"
	types "sigs.k8s.io/container-object-storage-interface-api/apis/objectstorage.k8s.io/v1alpha1"
	bucketclientset "sigs.k8s.io/container-object-storage-interface-api/clientset"
	"sigs.k8s.io/container-object-storage-interface-api/controller"
	"sigs.k8s.io/controller-tools/pkg/crd"
	crdmarkers "sigs.k8s.io/controller-tools/pkg/crd/markers"
	"sigs.k8s.io/controller-tools/pkg/genall"
	"sigs.k8s.io/controller-tools/pkg/loader"
	"sigs.k8s.io/controller-tools/pkg/markers"
	"k8s.io/klog/v2"
)
var (
	ErrBucketAlreadyExists        = errors.New("A bucket already existing that matches the bucket request")
	ErrInvalidBucketClass         = errors.New("Cannot find bucket class with the name specified in the bucket request")
	ErrBucketAccessAlreadyExists  = errors.New("A bucket access already existing that matches the bucket access request")
	ErrInvalidBucketAccessClass   = errors.New("Cannot find bucket access class with the name specified in the bucket access request")
	ErrInvalidBucketRequest       = errors.New("Invalid bucket request specified in the bucket access request")
	ErrInvalidBucketAccessRequest = errors.New("Invalid bucket access request specified")
	ErrWaitForBucketProvisioning  = errors.New("Bucket instance specified in the bucket request is not available to provision bucket access")
	ErrBCUnavailable              = errors.New("BucketClass is not available")
	ErrNotImplemented             = errors.New("Operation Not Implemented")
	ErrNilConfigMap               = errors.New("ConfigMap cannot be nil")
)
func CopySS(m map[string]string) map[string]string {
	if m == nil {
		return nil
	}
	copy := make(map[string]string, len(m))
	for k, v := range m {
		copy[k] = v
	}
	return copy
}
func CopyStrings(s []string) []string {
	if s == nil {
		return nil
	}
	c := make([]string, len(s))
	copy(c, s)
	return c
}
func GetUUID() string {
	return string(uuid.NewUUID())
}
func ReadConfigData(kubeClient kubeclientset.Interface, configMapRef *v1.ObjectReference) (string, error) {
	if configMapRef == nil {
		return "", ErrNilConfigMap
	}
	configMap, err := kubeClient.CoreV1().ConfigMaps(configMapRef.Namespace).Get(context.TODO(), configMapRef.Name, metav1.GetOptions{})
	if err != nil {
		return "", err
	}
	payload := make(map[string]string)
	for name, data := range configMap.Data {
		payload[name] = data
	}
	cData, err := json.Marshal(payload)
	if err != nil {
		return "", err
	}
	return string(cData), nil
}
func SetupTest(ctx context.Context) (bucketclientset.Interface, kubeclientset.Interface, *controller.ObjectStorageController) {
	config, err := func() (*rest.Config, error) {
		kubeConfig := os.Getenv("KUBECONFIG")
		if kubeConfig != "" {
			return clientcmd.BuildConfigFromFlags("", kubeConfig)
		}
		return rest.InClusterConfig()
	}()
	if err != nil {
		klog.Fatalf("Failed to create clients: %v", err)
	}
	kubeClient, err := kubeclientset.NewForConfig(config)
	if err != nil {
		klog.Fatalf("Failed to create Kubernetes client: %v", err)
	}
	client, err := bucketclientset.NewForConfig(config)
	if err != nil {
		klog.Fatalf("Failed to create ObjectStorage client: %v", err)
	}
	crdClientset, err := apiextensions.NewForConfig(config)
	if err != nil {
		klog.Fatalf("Failed to create CRD client: %v", err)
	}
	err = RegisterCRDs(ctx, crdClientset.CustomResourceDefinitions())
	if err != nil {
		klog.Fatalf("Failed to register CRDs: %v", err)
	}
	rateLimit := workqueue.NewMaxOfRateLimiter(
		workqueue.NewItemExponentialFailureRateLimiter(100*time.Millisecond, 600*time.Second),
		&workqueue.BucketRateLimiter{Limiter: rate.NewLimiter(rate.Limit(10), 100)},
	)
	ctrl, err := controller.NewObjectStorageControllerWithClientset("controller-manager", "leader-lock", 40, rateLimit, kubeClient, client)
	if err != nil {
		klog.Fatalf("Failed to create ObjectStorage Controller: %v", err)
	}
	go ctrl.Run(ctx)
	return client, kubeClient, ctrl
}
func GetBuckets(ctx context.Context, client bucketclientset.Interface, numExpected int) *types.BucketList {
	bucketList, err := client.ObjectstorageV1alpha1().Buckets().List(ctx, metav1.ListOptions{})
	if len(bucketList.Items) > 0 {
		return bucketList
	}
	numtimes := 0
	for numtimes < 10 {
		bucketList, err = client.ObjectstorageV1alpha1().Buckets().List(ctx, metav1.ListOptions{})
		if len(bucketList.Items) >= numExpected {
			return bucketList
		} else {
			klog.Errorf("Failed to fetch the bucket created %v", err)
		}
		numtimes++
		<-time.After(time.Duration(numtimes) * time.Second)
	}
	return &types.BucketList{}
}
func ValidateBucket(bucket types.Bucket, bucketrequest types.BucketRequest, bucketclass types.BucketClass) bool {
	if strings.HasPrefix(bucket.Name, bucketrequest.Spec.BucketPrefix) &&
		bucketrequest.Status.BucketName == bucket.Name &&
		bucket.Spec.BucketClassName == bucketrequest.Spec.BucketClassName &&
		bucket.Spec.BucketRequest.Name == bucketrequest.Name &&
		bucket.Spec.BucketRequest.Namespace == bucketrequest.Namespace &&
		bucket.Spec.BucketRequest.UID == bucketrequest.ObjectMeta.UID &&
		bucket.Spec.BucketClassName == bucketclass.Name &&
		reflect.DeepEqual(bucket.Spec.Parameters, bucketclass.Parameters) &&
		bucket.Spec.Provisioner == bucketclass.Provisioner &&
		bucket.Spec.DeletionPolicy == bucketclass.DeletionPolicy {
		return true
	}
	return false
}
func GetBucketAccesses(ctx context.Context, client bucketclientset.Interface, numExpected int) *types.BucketAccessList {
	bucketaccessList, _ := client.ObjectstorageV1alpha1().BucketAccesses().List(ctx, metav1.ListOptions{})
	if len(bucketaccessList.Items) > 0 {
		return bucketaccessList
	}
	numtimes := 0
	for numtimes < 10 {
		bucketaccessList, _ = client.ObjectstorageV1alpha1().BucketAccesses().List(ctx, metav1.ListOptions{})
		if len(bucketaccessList.Items) >= numExpected {
			return bucketaccessList
		}
		numtimes++
		<-time.After(time.Duration(numtimes) * time.Second)
	}
	return &types.BucketAccessList{}
}