@@ -44,17 +44,22 @@ const (
4444)
4545
4646const (
47- ErrNetworkAttachments = "not all pods have interfaces with ips as configured in NetworkAttachments: %s"
48- ErrReceivedUnexpectedAction = "unexpected action received"
49- ErrConfirmLockOwnership = "can not confirm ownership of %s lock"
47+ // ErrConfirmLockOwnership is the error message for lock ownership confirmation failures
48+ ErrConfirmLockOwnership = "can not confirm ownership of %s lock"
5049)
5150
5251const (
53- InfoWaitingOnPod = "Waiting on either pod to finish or release of the lock."
54- InfoTestingCompleted = "Testing completed. All pods spawned by the test-operator finished."
55- InfoCreatingFirstPod = "Creating first test pod (workflow step %d)."
56- InfoCreatingNextPod = "Creating next test pod (workflow step %d)."
52+ // InfoWaitingOnPod is the info message when waiting for pod completion or lock release
53+ InfoWaitingOnPod = "Waiting on either pod to finish or release of the lock."
54+ // InfoTestingCompleted is the info message when all testing is completed
55+ InfoTestingCompleted = "Testing completed. All pods spawned by the test-operator finished."
56+ // InfoCreatingFirstPod is the info message when creating the first test pod
57+ InfoCreatingFirstPod = "Creating first test pod (workflow step %d)."
58+ // InfoCreatingNextPod is the info message when creating subsequent test pods
59+ InfoCreatingNextPod = "Creating next test pod (workflow step %d)."
60+ // InfoCanNotAcquireLock is the info message when lock acquisition fails
5761 InfoCanNotAcquireLock = "Can not acquire %s lock."
62+ // InfoCanNotReleaseLock is the info message when lock release fails
5863 InfoCanNotReleaseLock = "Can not release %s lock."
5964)
6065
@@ -64,6 +69,22 @@ const (
6469 RequeueAfterValue = time .Second * 60
6570)
6671
72+ // Static error definitions for test operations
73+ var (
74+ // ErrReceivedUnexpectedAction indicates that an unexpected action was received.
75+ ErrReceivedUnexpectedAction = errors .New ("unexpected action received" )
76+
77+ // ErrFailedToDeleteLock indicates that the test-operator-lock could not be deleted.
78+ ErrFailedToDeleteLock = errors .New ("failed to delete test-operator-lock" )
79+
80+ // ErrNetworkAttachmentsMismatch indicates that not all pods have interfaces with IPs as configured in NetworkAttachments.
81+ ErrNetworkAttachmentsMismatch = errors .New ("not all pods have interfaces with ips as configured in NetworkAttachments" )
82+
83+ // ErrLockFieldMissing indicates that a required field is missing in the lock config map.
84+ ErrLockFieldMissing = errors .New ("field is missing in the config map" )
85+ )
86+
87+ // Reconciler provides common functionality for all test framework reconcilers
6788type Reconciler struct {
6889 Client client.Client
6990 Kclient kubernetes.Interface
@@ -232,6 +253,7 @@ func (r *Reconciler) GetLastPod(
232253 return maxPod , nil
233254}
234255
256+ // GetEnvVarsConfigMapName returns the name of the environment variables ConfigMap for the given instance and workflow step
235257func GetEnvVarsConfigMapName (instance interface {}, workflowStepNum int ) string {
236258 if _ , ok := instance .(* v1beta1.Tobiko ); ok {
237259 return "not-implemented"
@@ -242,6 +264,7 @@ func GetEnvVarsConfigMapName(instance interface{}, workflowStepNum int) string {
242264 return "not-implemented"
243265}
244266
267+ // GetCustomDataConfigMapName returns the name of the custom data ConfigMap for the given instance and workflow step
245268func GetCustomDataConfigMapName (instance interface {}, workflowStepNum int ) string {
246269 if _ , ok := instance .(* v1beta1.Tobiko ); ok {
247270 return "not-implemented"
@@ -252,6 +275,7 @@ func GetCustomDataConfigMapName(instance interface{}, workflowStepNum int) strin
252275 return "not-implemented"
253276}
254277
278+ // GetContainerImage returns the container image to use for the given instance, either from the provided parameter or from configuration
255279func (r * Reconciler ) GetContainerImage (
256280 ctx context.Context ,
257281 containerImage string ,
@@ -347,6 +371,7 @@ func (r *Reconciler) GetContainerImage(
347371 return "" , nil
348372}
349373
374+ // GetPodName returns the name of the pod for the given instance and workflow step
350375func (r * Reconciler ) GetPodName (instance interface {}, workflowStepNum int ) string {
351376 if typedInstance , ok := instance .(* v1beta1.Tobiko ); ok {
352377 if len (typedInstance .Spec .Workflow ) == 0 || workflowStepNum == workflowStepNumInvalid {
@@ -388,6 +413,7 @@ func (r *Reconciler) GetPodName(instance interface{}, workflowStepNum int) strin
388413 return workflowStepNameInvalid
389414}
390415
416+ // GetPVCLogsName returns the name of the PVC for logs for the given instance and workflow step
391417func (r * Reconciler ) GetPVCLogsName (instance client.Object , workflowStepNum int ) string {
392418 instanceName := instance .GetName ()
393419 instanceCreationTimestamp := instance .GetCreationTimestamp ().Format (time .UnixDate )
@@ -397,6 +423,7 @@ func (r *Reconciler) GetPVCLogsName(instance client.Object, workflowStepNum int)
397423 return instanceName + "-" + workflowStep + "-" + nameSuffix
398424}
399425
426+ // CheckSecretExists checks if a secret with the given name exists in the same namespace as the instance
400427func (r * Reconciler ) CheckSecretExists (ctx context.Context , instance client.Object , secretName string ) bool {
401428 secret := & corev1.Secret {}
402429 err := r .Client .Get (ctx , client.ObjectKey {Namespace : instance .GetNamespace (), Name : secretName }, secret )
@@ -407,6 +434,7 @@ func (r *Reconciler) CheckSecretExists(ctx context.Context, instance client.Obje
407434 return true
408435}
409436
437+ // GetStringHash returns a hash of the given string with the specified length
410438func GetStringHash (str string , hashLength int ) string {
411439 hash := sha256 .New ()
412440 hash .Write ([]byte (str ))
@@ -416,6 +444,7 @@ func GetStringHash(str string, hashLength int) string {
416444 return hashString [:hashLength ]
417445}
418446
447+ // EnsureLogsPVCExists ensures that a PVC for logs exists for the given instance and workflow step
419448func (r * Reconciler ) EnsureLogsPVCExists (
420449 ctx context.Context ,
421450 instance client.Object ,
@@ -464,18 +493,22 @@ func (r *Reconciler) EnsureLogsPVCExists(
464493 return ctrlResult , nil
465494}
466495
496+ // GetClient returns the Kubernetes client
467497func (r * Reconciler ) GetClient () client.Client {
468498 return r .Client
469499}
470500
501+ // GetLogger returns the logger instance
471502func (r * Reconciler ) GetLogger () logr.Logger {
472503 return r .Log
473504}
474505
506+ // GetScheme returns the runtime scheme
475507func (r * Reconciler ) GetScheme () * runtime.Scheme {
476508 return r .Scheme
477509}
478510
511+ // GetDefaultBool returns the string representation of a boolean value with default handling
479512func (r * Reconciler ) GetDefaultBool (variable bool ) string {
480513 if variable {
481514 return "true"
@@ -484,6 +517,7 @@ func (r *Reconciler) GetDefaultBool(variable bool) string {
484517 return "false"
485518}
486519
520+ // GetDefaultInt returns the string representation of an integer value with optional default value
487521func (r * Reconciler ) GetDefaultInt (variable int64 , defaultValue ... string ) string {
488522 if variable != 0 {
489523 return strconv .FormatInt (variable , 10 )
@@ -494,6 +528,7 @@ func (r *Reconciler) GetDefaultInt(variable int64, defaultValue ...string) strin
494528 return ""
495529}
496530
531+ // GetLockInfo retrieves the lock information ConfigMap for the given instance
497532func (r * Reconciler ) GetLockInfo (ctx context.Context , instance client.Object ) (* corev1.ConfigMap , error ) {
498533 cm := & corev1.ConfigMap {}
499534 objectKey := client.ObjectKey {Namespace : instance .GetNamespace (), Name : testOperatorLockName }
@@ -503,17 +538,13 @@ func (r *Reconciler) GetLockInfo(ctx context.Context, instance client.Object) (*
503538 }
504539
505540 if _ , ok := cm .Data [testOperatorLockOnwerField ]; ! ok {
506- errMsg := fmt .Sprintf (
507- "%s field is missing in the %s config map" ,
508- testOperatorLockOnwerField , testOperatorLockName ,
509- )
510-
511- return cm , errors .New (errMsg )
541+ return cm , fmt .Errorf ("%w: %s field is missing in the %s config map" , ErrLockFieldMissing , testOperatorLockOnwerField , testOperatorLockName )
512542 }
513543
514544 return cm , err
515545}
516546
547+ // AcquireLock attempts to acquire a lock for the given instance to prevent concurrent operations
517548func (r * Reconciler ) AcquireLock (
518549 ctx context.Context ,
519550 instance client.Object ,
@@ -552,6 +583,7 @@ func (r *Reconciler) AcquireLock(
552583 return false , err
553584}
554585
586+ // ReleaseLock releases the lock for the given instance
555587func (r * Reconciler ) ReleaseLock (ctx context.Context , instance client.Object ) (bool , error ) {
556588 Log := r .GetLogger ()
557589
@@ -585,9 +617,10 @@ func (r *Reconciler) ReleaseLock(ctx context.Context, instance client.Object) (b
585617 Log .Info ("Waiting for the test-operator-lock deletion!" )
586618 }
587619
588- return false , errors . New ( "failed to delete test-operator-lock" )
620+ return false , ErrFailedToDeleteLock
589621}
590622
623+ // PodExists checks if a pod exists for the given instance and workflow step
591624func (r * Reconciler ) PodExists (ctx context.Context , instance client.Object , workflowStepNum int ) bool {
592625 pod := & corev1.Pod {}
593626 podName := r .GetPodName (instance , workflowStepNum )
@@ -606,6 +639,7 @@ func (r *Reconciler) setConfigOverwrite(customData map[string]string, configOver
606639 }
607640}
608641
642+ // GetCommonRbacRules returns the common RBAC rules for test operations, with optional privileged permissions
609643func GetCommonRbacRules (privileged bool ) []rbacv1.PolicyRule {
610644 rbacPolicyRule := rbacv1.PolicyRule {
611645 APIGroups : []string {"security.openshift.io" },
@@ -623,7 +657,7 @@ func GetCommonRbacRules(privileged bool) []rbacv1.PolicyRule {
623657 return []rbacv1.PolicyRule {rbacPolicyRule }
624658}
625659
626- // Some frameworks like (e.g., Tobiko and Horizon) require password value to be
660+ // EnsureCloudsConfigMapExists ensures that frameworks like Tobiko and Horizon have password values
627661// present in clouds.yaml. This code ensures that we set a default value of
628662// 12345678 when password value is missing in the clouds.yaml
629663func EnsureCloudsConfigMapExists (
@@ -692,6 +726,7 @@ func EnsureCloudsConfigMapExists(
692726 return ctrl.Result {}, nil
693727}
694728
729+ // IsEmpty checks if the provided value is empty based on its type
695730func IsEmpty (value interface {}) bool {
696731 if v , ok := value .(reflect.Value ); ok {
697732 switch v .Kind () {
0 commit comments