...

Source file src/edge-infra.dev/test/f2/x/ktest/kpoll/checks.go

Documentation: edge-infra.dev/test/f2/x/ktest/kpoll

     1  package kpoll
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"gotest.tools/v3/poll"
     8  	"sigs.k8s.io/controller-runtime/pkg/client"
     9  
    10  	"edge-infra.dev/pkg/k8s/object"
    11  	"edge-infra.dev/pkg/k8s/runtime/inventory"
    12  	"edge-infra.dev/pkg/k8s/unstructured"
    13  )
    14  
    15  // Exists checks that all objs exist on the cluster.
    16  //
    17  // [edge-infra.dev/pkg/k8s/object.IsDeleted] is used to determine object
    18  // existence.
    19  func Exists(ctx context.Context, c client.Client, objs ...client.Object) poll.Check {
    20  	return func(_ poll.LogT) poll.Result {
    21  		return objsExist(ctx, c, objs...)
    22  	}
    23  }
    24  
    25  func objExists(ctx context.Context, c client.Client, o client.Object) poll.Result {
    26  	err := c.Get(ctx, client.ObjectKeyFromObject(o), o)
    27  	switch {
    28  	case err == nil && !object.IsDeleted(o, err):
    29  		return poll.Success()
    30  	case object.IsDeleted(o, err):
    31  		return poll.Continue("%s not present", object.FmtObject(o))
    32  	case err != nil:
    33  		// Error didn't indicate that the object doesn't exist, so return it
    34  		return poll.Error(err)
    35  	default:
    36  		return poll.Error(fmt.Errorf(
    37  			"unknown state: object should either be deleted or present",
    38  		))
    39  	}
    40  }
    41  
    42  func objsExist(ctx context.Context, c client.Client, objs ...client.Object) poll.Result {
    43  	if len(objs) == 1 {
    44  		return objExists(ctx, c, objs[0])
    45  	}
    46  
    47  	results := make([]poll.Result, len(objs))
    48  	for i, o := range objs {
    49  		results[i] = objExists(ctx, c, o)
    50  	}
    51  
    52  	return JoinResults(results...)
    53  }
    54  
    55  // Deleted checks that none of the provided objs exist on the cluster.
    56  //
    57  // [edge-infra.dev/pkg/k8s/object.IsDeleted] is used to determine object
    58  // existence.
    59  func Deleted(ctx context.Context, c client.Client, objs ...client.Object) poll.Check {
    60  	return func(_ poll.LogT) poll.Result {
    61  		return objsDeleted(ctx, c, objs...)
    62  	}
    63  }
    64  
    65  func objDeleted(ctx context.Context, c client.Client, o client.Object) poll.Result {
    66  	err := c.Get(ctx, client.ObjectKeyFromObject(o), o)
    67  	switch {
    68  	case object.IsDeleted(o, err):
    69  		return poll.Success()
    70  	case !object.IsDeleted(o, err):
    71  		return poll.Continue("%s present", object.FmtObject(o))
    72  	case err != nil:
    73  		// Error didn't indicate that the object doesn't exist, so return it
    74  		return poll.Error(err)
    75  	default:
    76  		return poll.Error(fmt.Errorf(
    77  			"unknown state: object should either be deleted or present",
    78  		))
    79  	}
    80  }
    81  
    82  func objsDeleted(ctx context.Context, c client.Client, objs ...client.Object) poll.Result {
    83  	if len(objs) == 1 {
    84  		return objDeleted(ctx, c, objs[0])
    85  	}
    86  
    87  	results := make([]poll.Result, len(objs))
    88  	for i, o := range objs {
    89  		results[i] = objDeleted(ctx, c, o)
    90  	}
    91  
    92  	return JoinResults(results...)
    93  }
    94  
    95  // InventoryPruned checks that the difference between the current and old
    96  // inventory no longer exists on the cluster.
    97  //
    98  // [edge-infra.dev/pkg/k8s/object.IsDeleted] is used to determine object
    99  // existence.
   100  func InventoryPruned(ctx context.Context, c client.Client, curr, old *inventory.ResourceInventory) poll.Check {
   101  	return func(_ poll.LogT) poll.Result {
   102  		diff, err := old.Diff(curr)
   103  		if err != nil {
   104  			return poll.Error(err)
   105  		}
   106  		if len(diff) == 0 {
   107  			return poll.Error(fmt.Errorf(
   108  				"can't validate pruning with identical inventories: no diff produced",
   109  			))
   110  		}
   111  
   112  		return objsDeleted(ctx, c, unstructured.ToClientObjArray(diff...)...)
   113  	}
   114  }
   115  
   116  // InventoryExists checks that all the objects in the inventory exist on the
   117  // cluster.
   118  //
   119  // TODO(aw185176): Could probably use ListMeta() and additional elbow grease to
   120  // avoid full parsing of unstructured objects and the multiple slice allocations
   121  // for type massaging
   122  func InventoryExists(ctx context.Context, c client.Client, exp *inventory.ResourceInventory) poll.Check {
   123  	return func(_ poll.LogT) poll.Result {
   124  		objs, err := exp.ListObjects()
   125  		if err != nil {
   126  			return poll.Error(err)
   127  		}
   128  		return objsExist(ctx, c, unstructured.ToClientObjArray(objs...)...)
   129  	}
   130  }
   131  

View as plain text