133 lines
3.6 KiB
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
|
|
}
|