Skip to content

Commit e881752

Browse files
committed
Add unit tests for UnpackBundle
1 parent bb13b90 commit e881752

File tree

3 files changed

+544
-32
lines changed

3 files changed

+544
-32
lines changed

pkg/controller/bundle/bundle_unpacker.go

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"crypto/sha256"
66
"fmt"
7+
"strings"
78
"time"
89

910
"github.com/operator-framework/operator-registry/pkg/api"
@@ -37,7 +38,7 @@ const (
3738
// and overrides the default specified by the --bundle-unpack-timeout flag
3839
// The time duration should be in the same format as accepted by time.ParseDuration()
3940
// e.g 1m30s
40-
BundleUnpackTimeoutAnnotationKey = "bundle-unpack-timeout"
41+
BundleUnpackTimeoutAnnotationKey = "operatorframework.io/bundle-unpack-timeout"
4142
)
4243

4344
type BundleUnpackResult struct {
@@ -220,7 +221,7 @@ func (c *ConfigMapUnpacker) job(cmRef *corev1.ObjectReference, bundlePath string
220221
//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . Unpacker
221222

222223
type Unpacker interface {
223-
UnpackBundle(lookup *operatorsv1alpha1.BundleLookup, annotationUnpackTimeout time.Duration) (result *BundleUnpackResult, err error)
224+
UnpackBundle(lookup *operatorsv1alpha1.BundleLookup, timeout time.Duration) (result *BundleUnpackResult, err error)
224225
}
225226

226227
type ConfigMapUnpacker struct {
@@ -367,7 +368,7 @@ const (
367368
NotUnpackedMessage = "bundle contents have not yet been persisted to installplan status"
368369
)
369370

370-
func (c *ConfigMapUnpacker) UnpackBundle(lookup *operatorsv1alpha1.BundleLookup, annotationUnpackTimeout time.Duration) (result *BundleUnpackResult, err error) {
371+
func (c *ConfigMapUnpacker) UnpackBundle(lookup *operatorsv1alpha1.BundleLookup, timeout time.Duration) (result *BundleUnpackResult, err error) {
371372

372373
result = newBundleUnpackResult(lookup)
373374

@@ -377,7 +378,7 @@ func (c *ConfigMapUnpacker) UnpackBundle(lookup *operatorsv1alpha1.BundleLookup,
377378
return result, nil
378379
}
379380

380-
// if pending condition is not true then bundle has already been unpacked(unknown) or failed(false)
381+
// if pending condition is not true then bundle has already been unpacked(unknown)
381382
pendingCond := result.GetCondition(operatorsv1alpha1.BundleLookupPending)
382383
if pendingCond.Status != corev1.ConditionTrue {
383384
return result, nil
@@ -430,33 +431,25 @@ func (c *ConfigMapUnpacker) UnpackBundle(lookup *operatorsv1alpha1.BundleLookup,
430431
secrets = append(secrets, corev1.LocalObjectReference{Name: secretName})
431432
}
432433
var job *batchv1.Job
433-
job, err = c.ensureJob(cmRef, result.Path, secrets, annotationUnpackTimeout)
434+
job, err = c.ensureJob(cmRef, result.Path, secrets, timeout)
434435
if err != nil {
435436
return
436437
}
437438

438439
// Check if bundle unpack job has failed due a timeout
439440
// Return a BundleJobError so we can mark the InstallPlan as Failed
440-
isFailed, jobCond := jobConditionTrue(job, batchv1.JobFailed)
441-
if isFailed {
441+
if jobCond, isFailed := getCondition(job, batchv1.JobFailed); isFailed {
442442
// Add the BundleLookupFailed condition with the message and reason from the job failure
443443
failedCond.Status = corev1.ConditionTrue
444444
failedCond.Reason = jobCond.Reason
445445
failedCond.Message = jobCond.Message
446446
failedCond.LastTransitionTime = &now
447447
result.SetCondition(failedCond)
448448

449-
// BundleLookupPending is false with reason being job failed
450-
pendingCond.Status = corev1.ConditionFalse
451-
pendingCond.Reason = JobFailedReason
452-
pendingCond.Message = JobFailedMessage
453-
pendingCond.LastTransitionTime = &now
454-
result.SetCondition(pendingCond)
455-
456449
return
457450
}
458451

459-
if isComplete, _ := jobConditionTrue(job, batchv1.JobComplete); !isComplete {
452+
if _, isComplete := getCondition(job, batchv1.JobComplete); !isComplete {
460453
// In the case of an image pull failure for a non-existent image the bundle unpack job
461454
// can stay pending until the ActiveDeadlineSeconds timeout ~10m
462455
// To indicate why it's pending we inspect the container statuses of the
@@ -508,12 +501,12 @@ func (c *ConfigMapUnpacker) UnpackBundle(lookup *operatorsv1alpha1.BundleLookup,
508501
}
509502

510503
func (c *ConfigMapUnpacker) pendingContainerStatusMessages(job *batchv1.Job) (string, error) {
511-
containerStatusMessages := ""
504+
containerStatusMessages := []string{}
512505
// List pods for unpack job
513506
podLabel := map[string]string{"job-name": job.GetName()}
514507
pods, listErr := c.podLister.Pods(job.GetNamespace()).List(k8slabels.SelectorFromSet(podLabel))
515508
if listErr != nil {
516-
return containerStatusMessages, fmt.Errorf("Failed to list pods for job(%s): %v", job.GetName(), listErr)
509+
return "", fmt.Errorf("Failed to list pods for job(%s): %v", job.GetName(), listErr)
517510
}
518511

519512
// Ideally there should be just 1 pod running but inspect all pods in the pending phase
@@ -531,13 +524,13 @@ func (c *ConfigMapUnpacker) pendingContainerStatusMessages(job *batchv1.Job) (st
531524
}
532525

533526
// Aggregate the wait reasons for all pending containers
534-
containerStatusMessages = containerStatusMessages +
527+
containerStatusMessages = append(containerStatusMessages,
535528
fmt.Sprintf("Unpack pod(%s/%s) container(%s) is pending. Reason: %s, Message: %s | ",
536-
pod.Namespace, pod.Name, ic.Name, ic.State.Waiting.Reason, ic.State.Waiting.Message)
529+
pod.Namespace, pod.Name, ic.Name, ic.State.Waiting.Reason, ic.State.Waiting.Message))
537530
}
538531
}
539532

540-
return containerStatusMessages, nil
533+
return strings.Join(containerStatusMessages, " | "), nil
541534
}
542535

543536
func (c *ConfigMapUnpacker) ensureConfigmap(csRef *corev1.ObjectReference, name string) (cm *corev1.ConfigMap, err error) {
@@ -554,8 +547,8 @@ func (c *ConfigMapUnpacker) ensureConfigmap(csRef *corev1.ObjectReference, name
554547
return
555548
}
556549

557-
func (c *ConfigMapUnpacker) ensureJob(cmRef *corev1.ObjectReference, bundlePath string, secrets []corev1.LocalObjectReference, annotationUnpackTimeout time.Duration) (job *batchv1.Job, err error) {
558-
fresh := c.job(cmRef, bundlePath, secrets, annotationUnpackTimeout)
550+
func (c *ConfigMapUnpacker) ensureJob(cmRef *corev1.ObjectReference, bundlePath string, secrets []corev1.LocalObjectReference, timeout time.Duration) (job *batchv1.Job, err error) {
551+
fresh := c.job(cmRef, bundlePath, secrets, timeout)
559552
job, err = c.jobLister.Jobs(fresh.GetNamespace()).Get(fresh.GetName())
560553
if err != nil {
561554
if apierrors.IsNotFound(err) {
@@ -686,17 +679,19 @@ func ownerRef(ref *corev1.ObjectReference) metav1.OwnerReference {
686679
}
687680
}
688681

689-
// jobConditionTrue returns true if the given job has the given condition with the given condition type true, and returns false otherwise.
682+
// getCondition returns true if the given job has the given condition with the given condition type true, and returns false otherwise.
690683
// Also returns the condition if true
691-
func jobConditionTrue(job *batchv1.Job, conditionType batchv1.JobConditionType) (bool, *batchv1.JobCondition) {
684+
func getCondition(job *batchv1.Job, conditionType batchv1.JobConditionType) (condition *batchv1.JobCondition, isTrue bool) {
692685
if job == nil {
693-
return false, nil
686+
return
694687
}
695688

696689
for _, cond := range job.Status.Conditions {
697690
if cond.Type == conditionType && cond.Status == corev1.ConditionTrue {
698-
return true, &cond
691+
condition = &cond
692+
isTrue = true
693+
return
699694
}
700695
}
701-
return false, nil
696+
return
702697
}

0 commit comments

Comments
 (0)