rollouts/pkg/util/grace/grace_wrapper_test.go

133 lines
3.6 KiB
Go

package grace
import (
"errors"
"testing"
"time"
)
func TestRunWithGraceSeconds(t *testing.T) {
tests := []struct {
name string
graceSeconds int32
modified bool
err error
expectedRetry bool
expectedErr error
}{
{name: "No modification, no grace period", graceSeconds: 0, modified: false, err: nil, expectedRetry: false, expectedErr: nil},
{name: "Modification, with grace period", graceSeconds: 10, modified: true, err: nil, expectedRetry: true, expectedErr: nil},
{name: "No modification, expectation unsatisfied", graceSeconds: 10, modified: false, err: nil, expectedRetry: true, expectedErr: nil},
{name: "Function returns error", graceSeconds: 10, modified: false, err: errors.New("test error"), expectedRetry: true, expectedErr: errors.New("test error")},
}
graceExpectations := NewGraceExpectations()
for _, cs := range tests {
t.Run(cs.name, func(t *testing.T) {
f := func() (bool, error) {
return cs.modified, cs.err
}
retry, _, err := runWithGraceSeconds(graceExpectations, "testKey", "create", cs.graceSeconds, f)
if retry != cs.expectedRetry {
t.Errorf("expected retry: %v, got: %v", cs.expectedRetry, retry)
}
if !equalErr(err, cs.expectedErr) {
t.Errorf("expected error: %v, got: %v", cs.expectedErr, err)
}
})
}
// Additional test to verify the timeout behavior
t.Run("Satisfaction of expectation over time", func(t *testing.T) {
graceSeconds := int32(1) // 1 second grace period
graceExpectations := NewGraceExpectations()
f := func() (bool, error) {
return true, nil
}
retry, _, err := runWithGraceSeconds(graceExpectations, "testKey2", "delete", graceSeconds, f)
if retry != true {
t.Errorf("expected retry: true after modification, got: %v", retry)
}
if err != nil {
t.Errorf("expected no error, got: %v", err)
}
// Wait for the grace period to be satisfied
time.Sleep(time.Duration(graceSeconds) * time.Second)
f2 := func() (bool, error) {
return false, nil
}
retry, _, err = runWithGraceSeconds(graceExpectations, "testKey2", "delete", graceSeconds, f2)
if retry != false {
t.Errorf("expected retry: false after grace period satisfied, got: %v", retry)
}
if err != nil {
t.Errorf("expected no error, got: %v", err)
}
})
}
// Comprehensive test for RunWithGraceSeconds using testFunction
func TestRunWithGraceSecondsComprehensive(t *testing.T) {
graceExpectations := NewGraceExpectations()
tests := []struct {
name string
expectedState int
graceSeconds int32
expectedRetry bool
expectedErr error
}{
{"No modification needed", 0, 0, false, nil},
{"Initial modification, create expectation", 1, 10, true, nil},
{"Function errors", -1, 10, true, errors.New("test error")},
}
for _, cs := range tests {
t.Run(cs.name, func(t *testing.T) {
f := testFunction(cs.expectedState)
retry, _, err := runWithGraceSeconds(graceExpectations, cs.name, "create", cs.graceSeconds, f)
if !equalErr(err, cs.expectedErr) {
t.Errorf("%s: expected error: %v, but got none", cs.name, cs.expectedErr)
}
if retry != cs.expectedRetry {
t.Errorf("%s: expected retry: %v, got: %v", cs.name, cs.expectedRetry, retry)
}
})
}
}
// Test function generator
func testFunction(expectedState int) func() (bool, error) {
currentState := 0
return func() (bool, error) {
if expectedState < 0 {
return true, errors.New("test error")
}
if currentState == expectedState {
return false, nil
} else {
currentState++
return true, nil
}
}
}
func equalErr(err1, err2 error) bool {
if err1 == nil && err2 == nil {
return true
}
if err1 != nil && err2 != nil {
return true
}
return false
}