package factory
import (
"errors"
"fmt"
"strings"
"testing"
"time"
kapi "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
buildapi "github.com/openshift/origin/pkg/build/api"
controller "github.com/openshift/origin/pkg/controller"
)
type buildUpdater struct {
Build *buildapi.Build
}
func (b *buildUpdater) Update(namespace string, build *buildapi.Build) error {
b.Build = build
return nil
}
func TestLimitedLogAndRetryFinish(t *testing.T) {
updater := &buildUpdater{}
err := errors.New("funky error")
now := unversioned.Now()
retry := controller.Retry{
Count: 0,
StartTimestamp: unversioned.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute()-31, now.Second(), now.Nanosecond(), now.Location()),
}
if limitedLogAndRetry(updater, 30*time.Minute)(&buildapi.Build{Status: buildapi.BuildStatus{Phase: buildapi.BuildPhaseNew}}, err, retry) {
t.Error("Expected no more retries after reaching timeout!")
}
if updater.Build == nil {
t.Fatal("BuildUpdater wasn't called!")
}
if updater.Build.Status.Phase != buildapi.BuildPhaseFailed {
t.Errorf("Expected status %s, got %s!", buildapi.BuildPhaseFailed, updater.Build.Status.Phase)
}
if !strings.Contains(updater.Build.Status.Message, "Funky error.") {
t.Errorf("Expected message to contain %v, got %s!", err.Error(), updater.Build.Status.Message)
}
if updater.Build.Status.CompletionTimestamp == nil {
t.Error("Expected CompletionTimestamp to be set!")
}
}
func TestLimitedLogAndRetryProcessing(t *testing.T) {
updater := &buildUpdater{}
err := errors.New("funky error")
now := unversioned.Now()
retry := controller.Retry{
Count: 0,
StartTimestamp: unversioned.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute()-10, now.Second(), now.Nanosecond(), now.Location()),
}
if !limitedLogAndRetry(updater, 30*time.Minute)(&buildapi.Build{Status: buildapi.BuildStatus{Phase: buildapi.BuildPhaseNew}}, err, retry) {
t.Error("Expected more retries!")
}
if updater.Build != nil {
t.Fatal("BuildUpdater shouldn't be called!")
}
}
func TestControllerRetryFunc(t *testing.T) {
obj := &kapi.Pod{}
obj.Name = "testpod"
obj.Namespace = "testNS"
testErr := fmt.Errorf("test error")
tests := []struct {
name string
retryCount int
isFatal func(err error) bool
err error
expect bool
}{
{
name: "maxRetries-1 retries",
retryCount: maxRetries - 1,
err: testErr,
expect: true,
},
{
name: "maxRetries+1 retries",
retryCount: maxRetries + 1,
err: testErr,
expect: false,
},
{
name: "isFatal returns true",
retryCount: 0,
err: testErr,
isFatal: func(err error) bool {
if err != testErr {
t.Errorf("Unexpected error: %v", err)
}
return true
},
expect: false,
},
{
name: "isFatal returns false",
retryCount: 0,
err: testErr,
isFatal: func(err error) bool {
if err != testErr {
t.Errorf("Unexpected error: %v", err)
}
return false
},
expect: true,
},
}
for _, tc := range tests {
f := retryFunc("test kind", tc.isFatal)
result := f(obj, tc.err, controller.Retry{Count: tc.retryCount})
if result != tc.expect {
t.Errorf("%s: unexpected result. Expected: %v. Got: %v", tc.name, tc.expect, result)
}
}
}