// TestURLBackoffFunctionality generally tests the URLBackoff wrapper. We avoid duplicating tests from backoff and request. func TestURLBackoffFunctionality(t *testing.T) { myBackoff := &URLBackoff{ Backoff: flowcontrol.NewBackOff(1*time.Second, 60*time.Second), } // Now test that backoff increases, then recovers. // 200 and 300 should both result in clearing the backoff. // all others like 429 should result in increased backoff. seconds := []int{0, 1, 2, 4, 8, 0, 1, 2} returnCodes := []int{ 429, 500, 501, 502, 300, 500, 501, 502, } if len(seconds) != len(returnCodes) { t.Fatalf("responseCode to backoff arrays should be the same length... sanity check failed.") } for i, sec := range seconds { backoffSec := myBackoff.CalculateBackoff(parse("http://1.2.3.4:100")) if backoffSec < time.Duration(sec)*time.Second || backoffSec > time.Duration(sec+5)*time.Second { t.Errorf("Backoff out of range %v: %v %v", i, sec, backoffSec) } myBackoff.UpdateBackoff(parse("http://1.2.3.4:100/responseCodeForFuncTest"), nil, returnCodes[i]) } if myBackoff.CalculateBackoff(parse("http://1.2.3.4:100")) == 0 { t.Errorf("The final return code %v should have resulted in a backoff ! ", returnCodes[7]) } }
func TestURLBackoffFunctionalityCollisions(t *testing.T) { myBackoff := &URLBackoff{ Backoff: flowcontrol.NewBackOff(1*time.Second, 60*time.Second), } // Add some noise and make sure backoff for a clean URL is zero. myBackoff.UpdateBackoff(parse("http://100.200.300.400:8080"), nil, 500) myBackoff.UpdateBackoff(parse("http://1.2.3.4:8080"), nil, 500) if myBackoff.CalculateBackoff(parse("http://1.2.3.4:100")) > 0 { t.Errorf("URLs are colliding in the backoff map!") } }
// readExpBackoffConfig handles the internal logic of determining what the // backoff policy is. By default if no information is available, NoBackoff. // TODO Generalize this see #17727 . func readExpBackoffConfig() BackoffManager { backoffBase := os.Getenv(envBackoffBase) backoffDuration := os.Getenv(envBackoffDuration) backoffBaseInt, errBase := strconv.ParseInt(backoffBase, 10, 64) backoffDurationInt, errDuration := strconv.ParseInt(backoffDuration, 10, 64) if errBase != nil || errDuration != nil { return &NoBackoff{} } return &URLBackoff{ Backoff: flowcontrol.NewBackOff( time.Duration(backoffBaseInt)*time.Second, time.Duration(backoffDurationInt)*time.Second)} }
// Disable makes the backoff trivial, i.e., sets it to zero. This might be used // by tests which want to run 1000s of mock requests without slowing down. func (b *URLBackoff) Disable() { glog.V(4).Infof("Disabling backoff strategy") b.Backoff = flowcontrol.NewBackOff(0*time.Second, 0*time.Second) }