...

Source file src/edge-infra.dev/pkg/k8s/runtime/conditions/merge_test.go

Documentation: edge-infra.dev/pkg/k8s/runtime/conditions

     1  package conditions
     2  
     3  import (
     4  	"testing"
     5  
     6  	. "github.com/onsi/gomega" //nolint:revive // TODO(aw185176): remove
     7  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     8  
     9  	"edge-infra.dev/pkg/k8s/meta/status"
    10  	"edge-infra.dev/pkg/k8s/object/fobject"
    11  )
    12  
    13  func TestNewConditionsGroup(t *testing.T) {
    14  	g := NewWithT(t)
    15  
    16  	negativeFalseReconciling := FalseCondition(status.ReconcilingCondition, "reason reconciling1", "message reconciling1")
    17  	negativeTrueStalled := TrueCondition(status.StalledCondition, "reason stalled1", "message stalled1")
    18  	negativeUnknownReconciling := UnknownCondition(status.ReconcilingCondition, "reason reconciling2", "message reconciling2")
    19  
    20  	conditions := []*metav1.Condition{nil1, true1, true1, false1, unknown1, negativeFalseReconciling, negativeTrueStalled, negativeUnknownReconciling}
    21  
    22  	got := getConditionGroups(conditionsWithSource(&fobject.Fake{}, conditions...), &mergeOptions{
    23  		negativePolarityConditionTypes: []string{status.ReconcilingCondition, status.StalledCondition},
    24  	})
    25  
    26  	g.Expect(got).ToNot(BeNil())
    27  	g.Expect(got).To(HaveLen(6))
    28  
    29  	// The TopGroup should be True/Negative and it should have one condition
    30  	g.Expect(got.TopGroup().status).To(Equal(metav1.ConditionTrue))
    31  	g.Expect(got.TopGroup().negativePolarity).To(BeTrue())
    32  	g.Expect(got.TopGroup().conditions).To(HaveLen(1))
    33  
    34  	// The TruePositivePolarityGroup should be True/Positive and it should have one condition
    35  	g.Expect(got.TruePositivePolarityGroup().status).To(Equal(metav1.ConditionTrue))
    36  	g.Expect(got.TruePositivePolarityGroup().negativePolarity).To(BeFalse())
    37  	g.Expect(got.TruePositivePolarityGroup().conditions).To(HaveLen(2))
    38  
    39  	// got[0] should be True/Negative and it should have one condition
    40  	g.Expect(got[0].status).To(Equal(metav1.ConditionTrue))
    41  	g.Expect(got[0].negativePolarity).To(BeTrue())
    42  	g.Expect(got[0].conditions).To(HaveLen(1))
    43  
    44  	// got[1] should be False/Positive and it should have one conditions
    45  	g.Expect(got[1].status).To(Equal(metav1.ConditionFalse))
    46  	g.Expect(got[1].negativePolarity).To(BeFalse())
    47  	g.Expect(got[1].conditions).To(HaveLen(1))
    48  
    49  	// got[2] should be True/Positive and it should have two conditions
    50  	g.Expect(got[2].status).To(Equal(metav1.ConditionTrue))
    51  	g.Expect(got[1].negativePolarity).To(BeFalse())
    52  	g.Expect(got[2].conditions).To(HaveLen(2))
    53  
    54  	// got[3] should be False/Negative and it should have one condition
    55  	g.Expect(got[3].status).To(Equal(metav1.ConditionFalse))
    56  	g.Expect(got[3].negativePolarity).To(BeTrue())
    57  	g.Expect(got[3].conditions).To(HaveLen(1))
    58  
    59  	// got[4] should be Unknown/Positive and it should have one condition
    60  	g.Expect(got[4].status).To(Equal(metav1.ConditionUnknown))
    61  	g.Expect(got[4].negativePolarity).To(BeFalse())
    62  	g.Expect(got[4].conditions).To(HaveLen(1))
    63  
    64  	// got[5] should be Unknown/Negative and it should have one condition
    65  	g.Expect(got[5].status).To(Equal(metav1.ConditionUnknown))
    66  	g.Expect(got[5].negativePolarity).To(BeTrue())
    67  	g.Expect(got[3].conditions).To(HaveLen(1))
    68  
    69  	// nil conditions are ignored
    70  }
    71  
    72  func TestMergeRespectPriority(t *testing.T) {
    73  	tests := []struct {
    74  		name               string
    75  		negativeConditions []string
    76  		conditions         []*metav1.Condition
    77  		want               *metav1.Condition
    78  	}{
    79  		{
    80  			name:       "aggregate nil list return nil",
    81  			conditions: nil,
    82  			want:       nil,
    83  		},
    84  		{
    85  			name:       "aggregate empty list return nil",
    86  			conditions: []*metav1.Condition{},
    87  			want:       nil,
    88  		},
    89  		{
    90  			name:               "When there is True/Negative it returns an inverted False/Positive",
    91  			negativeConditions: []string{true1.Type},
    92  			conditions:         []*metav1.Condition{false1, false1, false1, unknown1, true1},
    93  			want:               FalseCondition("foo", "reason true1", "message true1"),
    94  		},
    95  		{
    96  			name:       "When there is False/Positive and no True/Negative, it returns False/Positive",
    97  			conditions: []*metav1.Condition{false1, false1, unknown1, true1},
    98  			want:       FalseCondition("foo", "reason false1", "message false1"),
    99  		},
   100  		{
   101  			name:               "When there is True/Positive and no True/Negative or False/Positive, it returns True/Positive",
   102  			negativeConditions: []string{false1.Type},
   103  			conditions:         []*metav1.Condition{false1, unknown1, true1},
   104  			want:               TrueCondition("foo", "reason true1", "message true1"),
   105  		},
   106  		{
   107  			name:               "When there is True/Positive and no False/Positive, it returns True/Positive",
   108  			negativeConditions: []string{false1.Type},
   109  			conditions:         []*metav1.Condition{unknown1, true1, false1},
   110  			want:               TrueCondition("foo", "reason true1", "message true1"),
   111  		},
   112  		{
   113  			name:               "When there is False/Negative and no True/* or False/Positive, it returns False/Negative",
   114  			negativeConditions: []string{false1.Type},
   115  			conditions:         []*metav1.Condition{unknown1, false1},
   116  			want:               TrueCondition("foo", "reason false1", "message false1"),
   117  		},
   118  		{
   119  			name:       "When there is Unknown/* but no False/*, it returns Unknown/*",
   120  			conditions: []*metav1.Condition{unknown1},
   121  			want:       UnknownCondition("foo", "reason unknown1", "message unknown1"),
   122  		},
   123  		{
   124  			name:               "When the target condition is inverted, it returns an inverted condition",
   125  			negativeConditions: []string{"foo"},
   126  			conditions:         []*metav1.Condition{true1},
   127  			want:               FalseCondition("foo", "reason true1", "message true1"),
   128  		},
   129  		{
   130  			name:               "When the top and target conditions are inverted, it returns an equal condition",
   131  			negativeConditions: []string{"foo", true1.Type},
   132  			conditions:         []*metav1.Condition{true1},
   133  			want:               TrueCondition("foo", "reason true1", "message true1"),
   134  		},
   135  		{
   136  			name:       "nil conditions are ignored",
   137  			conditions: []*metav1.Condition{nil1, nil1, nil1},
   138  			want:       nil,
   139  		},
   140  	}
   141  
   142  	for _, tt := range tests {
   143  		t.Run(tt.name, func(t *testing.T) {
   144  			g := NewWithT(t)
   145  
   146  			got := merge(conditionsWithSource(&fobject.Fake{}, tt.conditions...), "foo", &mergeOptions{
   147  				negativePolarityConditionTypes: tt.negativeConditions,
   148  			})
   149  
   150  			if tt.want == nil {
   151  				g.Expect(got).To(BeNil())
   152  				return
   153  			}
   154  			g.Expect(got).To(HaveSameStateOf(tt.want))
   155  		})
   156  	}
   157  }
   158  
   159  func TestMergeRespectGeneration(t *testing.T) {
   160  	tests := []struct {
   161  		name               string
   162  		negativeConditions []string
   163  		conditions         []*metav1.Condition
   164  		mergeOpts          []MergeOption
   165  		want               *metav1.Condition
   166  	}{
   167  		{
   168  			name:               "without generation",
   169  			negativeConditions: []string{true1.Type},
   170  			conditions: []*metav1.Condition{
   171  				conditionWithGeneration(false1, 1),
   172  				conditionWithGeneration(true1, 2),
   173  				conditionWithGeneration(unknown1, 3),
   174  			},
   175  			want: FalseCondition("foo", "reason true1", "message true1"),
   176  		},
   177  		{
   178  			name:               "with generation",
   179  			negativeConditions: []string{true1.Type},
   180  			conditions: []*metav1.Condition{
   181  				conditionWithGeneration(false1, 1),
   182  				conditionWithGeneration(unknown1, 4),
   183  				conditionWithGeneration(true1, 4),
   184  			},
   185  			mergeOpts: []MergeOption{WithLatestGeneration()},
   186  			want:      FalseCondition("foo", "reason true1", "message true1"),
   187  		},
   188  	}
   189  
   190  	for _, tt := range tests {
   191  		t.Run(tt.name, func(t *testing.T) {
   192  			g := NewWithT(t)
   193  
   194  			mo := &mergeOptions{
   195  				negativePolarityConditionTypes: tt.negativeConditions,
   196  			}
   197  			for _, o := range tt.mergeOpts {
   198  				o(mo)
   199  			}
   200  			got := merge(conditionsWithSource(&fobject.Fake{}, tt.conditions...), "foo", mo)
   201  			g.Expect(got).To(HaveSameStateOf(tt.want))
   202  		})
   203  	}
   204  }
   205  
   206  func conditionsWithSource(obj Setter, conditions ...*metav1.Condition) []localizedCondition {
   207  	obj.SetConditions(conditionList(conditions...))
   208  
   209  	ret := []localizedCondition{}
   210  	for i := range conditions {
   211  		ret = append(ret, localizedCondition{
   212  			Condition: conditions[i],
   213  			Getter:    obj,
   214  		})
   215  	}
   216  
   217  	return ret
   218  }
   219  
   220  func conditionWithGeneration(condition *metav1.Condition, generation int64) *metav1.Condition {
   221  	condition.ObservedGeneration = generation
   222  	return condition
   223  }
   224  

View as plain text