Skip to content

Commit cde3abb

Browse files
committed
fix: initialize retry count at 1 and validate MaxRetryAttempts
Address CodeRabbit findings: - Initialize RetryCount to 1 on first attempt (was 0) - Update test expectations to match 1,2,3 sequence - Add validation to reject negative MaxRetryAttempts - Add tests for MaxRetryAttempts validation The retry count now accurately reflects the number of remediation attempts (first attempt = 1), and the config validation prevents invalid negative values while preserving 0 as unlimited. Signed-off-by: Billard <82095453+iacker@users.noreply.github.com>
1 parent ad7b881 commit cde3abb

4 files changed

Lines changed: 40 additions & 11 deletions

File tree

fault-remediation/pkg/annotation/annotation.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ func (m *NodeAnnotationManager) UpdateRemediationState(ctx context.Context, node
106106

107107
// Increment retry count if this group already exists
108108
existingGroup, exists := state.EquivalenceGroups[group]
109-
retryCount := 0
109+
retryCount := 1
110110
if exists {
111111
retryCount = existingGroup.RetryCount + 1
112112
}

fault-remediation/pkg/annotation/retry_count_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,29 +40,29 @@ func TestRetryCountIncrementsOnUpdate(t *testing.T) {
4040
client := fake.NewClientBuilder().WithObjects(node).Build()
4141
annotationManager := NodeAnnotationManager{client: client}
4242

43-
// First update - retry count should be 0
43+
// First update - retry count should be 1
4444
err := annotationManager.UpdateRemediationState(ctx, nodeName, groupName, "cr-1", "RESTART_BM")
4545
require.NoError(t, err)
4646

4747
state, _, err := annotationManager.GetRemediationState(ctx, nodeName)
4848
require.NoError(t, err)
49-
assert.Equal(t, 0, state.EquivalenceGroups[groupName].RetryCount, "First attempt should have retry count 0")
49+
assert.Equal(t, 1, state.EquivalenceGroups[groupName].RetryCount, "First attempt should have retry count 1")
5050

51-
// Second update - retry count should be 1
51+
// Second update - retry count should be 2
5252
err = annotationManager.UpdateRemediationState(ctx, nodeName, groupName, "cr-2", "RESTART_BM")
5353
require.NoError(t, err)
5454

5555
state, _, err = annotationManager.GetRemediationState(ctx, nodeName)
5656
require.NoError(t, err)
57-
assert.Equal(t, 1, state.EquivalenceGroups[groupName].RetryCount, "Second attempt should have retry count 1")
57+
assert.Equal(t, 2, state.EquivalenceGroups[groupName].RetryCount, "Second attempt should have retry count 2")
5858

59-
// Third update - retry count should be 2
59+
// Third update - retry count should be 3
6060
err = annotationManager.UpdateRemediationState(ctx, nodeName, groupName, "cr-3", "RESTART_BM")
6161
require.NoError(t, err)
6262

6363
state, _, err = annotationManager.GetRemediationState(ctx, nodeName)
6464
require.NoError(t, err)
65-
assert.Equal(t, 2, state.EquivalenceGroups[groupName].RetryCount, "Third attempt should have retry count 2")
65+
assert.Equal(t, 3, state.EquivalenceGroups[groupName].RetryCount, "Third attempt should have retry count 3")
6666
}
6767

6868
func TestRetryCountIndependentPerGroup(t *testing.T) {
@@ -92,8 +92,8 @@ func TestRetryCountIndependentPerGroup(t *testing.T) {
9292
state, _, err := annotationManager.GetRemediationState(ctx, nodeName)
9393
require.NoError(t, err)
9494

95-
assert.Equal(t, 1, state.EquivalenceGroups["group-1"].RetryCount, "group-1 should have retry count 1")
96-
assert.Equal(t, 0, state.EquivalenceGroups["group-2"].RetryCount, "group-2 should have retry count 0")
95+
assert.Equal(t, 2, state.EquivalenceGroups["group-1"].RetryCount, "group-1 should have retry count 2")
96+
assert.Equal(t, 1, state.EquivalenceGroups["group-2"].RetryCount, "group-2 should have retry count 1")
9797
}
9898

9999
func TestRetryCountPersistsAcrossPodRestarts(t *testing.T) {
@@ -123,6 +123,6 @@ func TestRetryCountPersistsAcrossPodRestarts(t *testing.T) {
123123
// Verify retry count persisted
124124
state, _, err := manager2.GetRemediationState(ctx, nodeName)
125125
require.NoError(t, err)
126-
assert.Equal(t, 1, state.EquivalenceGroups[groupName].RetryCount,
126+
assert.Equal(t, 2, state.EquivalenceGroups[groupName].RetryCount,
127127
"Retry count should persist across pod restarts")
128128
}

fault-remediation/pkg/config/config.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ type TomlConfig struct {
105105
// surface their own error before any cross-reference error they may also
106106
// participate in.
107107
func (c *TomlConfig) Validate() error {
108+
if c.MaxRetryAttempts < 0 {
109+
return fmt.Errorf("maxRetryAttempts must be non-negative (got %d); use 0 for unlimited retries", c.MaxRetryAttempts)
110+
}
111+
108112
if err := c.validateTemplate(); err != nil {
109113
return err
110114
}

fault-remediation/pkg/config/config_test.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,37 @@ func TestTomlConfig_Validate(t *testing.T) {
4747
{
4848
name: "empty template mountPath should be rejected",
4949
config: TomlConfig{
50-
Template: Template{MountPath: ""},
50+
Template: Template{MountPath: ""},
5151
RemediationActions: map[string]MaintenanceResource{},
5252
},
5353
expectError: true,
5454
errorSubstr: "template mountPath must be non-empty",
5555
},
56+
{
57+
name: "negative maxRetryAttempts should be rejected",
58+
config: TomlConfig{
59+
Template: Template{MountPath: tempDir},
60+
MaxRetryAttempts: -1,
61+
RemediationActions: map[string]MaintenanceResource{},
62+
},
63+
expectError: true,
64+
errorSubstr: "maxRetryAttempts must be non-negative",
65+
},
66+
{
67+
name: "zero maxRetryAttempts should be accepted (unlimited)",
68+
config: TomlConfig{
69+
Template: Template{MountPath: tempDir},
70+
MaxRetryAttempts: 0,
71+
RemediationActions: map[string]MaintenanceResource{
72+
"ACTION_A": {
73+
TemplateFileName: "template-a.yaml",
74+
Scope: "Cluster",
75+
EquivalenceGroup: "restart",
76+
},
77+
},
78+
},
79+
expectError: false,
80+
},
5681
{
5782
name: "valid config with matching templates",
5883
config: TomlConfig{

0 commit comments

Comments
 (0)