def test_elapsed(self): backoff = Backoff() assert backoff.elapsed(None) == backoff.zero now = datetime.utcnow() sleep_delta = timedelta(0, 0, 0, 1) sleep((sleep_delta * 2).total_seconds()) assert backoff.elapsed(now) > sleep_delta
def test_delta(self): backoff = Backoff() for attempt in range(backoff.max_attempts): if attempt == 0: assert backoff.delta(attempt) == timedelta() continue assert backoff.delta(attempt) == backoff.deltas[attempt] assert backoff.delta(attempt) == timedelta(seconds=2**attempt) # Should cap at max_attempts to highest delta assert backoff.delta(backoff.max_attempts + 20) == timedelta(seconds=2**backoff.max_attempts)
def test_init_deltas(self): count = 30 backoff = Backoff(count, [ timedelta(seconds=2**attempt if attempt > 0 else 0) for attempt in range(count + 1) ]) for attempt in range(count): if attempt == 0: assert backoff.delta(attempt) == timedelta() continue assert backoff.delta(attempt) == backoff.deltas[attempt] assert backoff.delta(attempt) == timedelta(seconds=2**attempt)
def test_init_backoff(self): b = Backoff(10) assert b.max_attempts == 10 q = Queue(backoff=b) assert q.maxsize == Queue.MAX_SIZE assert isinstance(q._backoff, Backoff) assert q._backoff.max_attempts == 10
def test_init_backoff(self): b = Backoff() tracker = Tracker(b) tracker2 = Tracker() assert tracker.backoff == b assert tracker2.backoff != b assert tracker.attempts == 0 assert tracker.last_attempt is None
def test_all_attempts_edge(self): backoff = Backoff() assert backoff.max_attempts == Backoff.max_attempts assert len(backoff.deltas) == 16 for edge in [-1, 0, 15, 16, 17]: assert backoff.delta(edge) >= backoff.zero assert backoff.remaining(edge, datetime.utcnow()) >= backoff.zero if edge > 0: assert backoff.expires(edge, datetime.utcnow()) >= datetime.utcnow() assert backoff.expired(edge, datetime.utcnow()) == False else: assert backoff.expires(edge, datetime.utcnow()) <= datetime.utcnow() assert backoff.expired(edge, datetime.utcnow())
def test_expires(self): backoff = Backoff() for attempt in range(backoff.max_attempts): now = datetime.utcnow() if attempt == 0: assert backoff.expires(attempt, now) < datetime.utcnow() continue expect_delta = timedelta(seconds=2**attempt) assert backoff.expires(attempt, now) > datetime.utcnow() assert backoff.expires(attempt, now - expect_delta) < datetime.utcnow() assert backoff.expires(attempt, now - (expect_delta * 2)) < datetime.utcnow() assert backoff.expires(attempt, now + expect_delta) > datetime.utcnow() assert backoff.expires(attempt, now + (expect_delta * 2)) > datetime.utcnow()
def test_expired(self): backoff = Backoff() for attempt in range(backoff.max_attempts): now = datetime.utcnow() if attempt == 0: assert backoff.expired(0, now) == True continue expect_delta = timedelta(seconds=2**attempt) assert backoff.expired(attempt, datetime.utcnow()) == False assert backoff.expired(attempt, datetime.utcnow() - (expect_delta / 2)) == False assert backoff.expired(attempt, datetime.utcnow() - expect_delta) == True assert backoff.expired(attempt, datetime.utcnow() - (expect_delta * 2)) == True
def test_remaining(self): backoff = Backoff() for attempt in range(backoff.max_attempts): now = datetime.utcnow() if attempt == 0: assert backoff.remaining(attempt, now) == timedelta() continue expect_delta = timedelta(seconds=2**attempt) assert backoff.remaining(attempt, now) > timedelta() assert backoff.remaining(attempt, now) < expect_delta assert backoff.remaining(attempt, now - expect_delta) == timedelta() assert backoff.remaining(attempt, now + expect_delta) > expect_delta
def test_wait(self): backoff = Backoff() sleep_delta = timedelta(0, 0, 0, 5) for attempt in range(backoff.max_attempts): now = datetime.utcnow() if attempt == 0: # Wait with 0 attempts should always be instant, 500 microsec buffer # here for when that carbon black is going hard at 100% backoff.wait(0, now) assert datetime.utcnow() < (now + timedelta(0, 0, 500)) continue # Every attempt we expect a (5 millisec) sleep when calling wait delta = timedelta(seconds=2**attempt) last_attempt = (now - delta) + sleep_delta expect = now - delta backoff.wait(attempt, last_attempt) assert datetime.utcnow() > expect
def test_expires_overflow(self): backoff = Backoff() assert backoff.expires(15, datetime.max) == datetime.max assert backoff.expires(16, datetime.max) == datetime.max
def test_init_max_attempts_exceeds_deltas(self): with pytest.raises(IndexError) as excinfo: Backoff(2, deltas=[]) assert '`max_attempts` must not exceed the length of deltas' == str( excinfo.value)
def test_init_max_attempts_is_zero(self): with pytest.raises(ValueError) as excinfo: Backoff(0) assert '`max_attempts` must be greater than zero' == str(excinfo.value)
def test_init_max_attempts(self): backoff = Backoff(10) assert backoff.max_attempts == 10 assert len(backoff.deltas) == 11
def test_init(self): backoff = Backoff() assert backoff.max_attempts == Backoff.max_attempts assert len(backoff.deltas) == 16
def test_str(self): assert str(Backoff()) == 'Backoff(max_attempts={0})'.format( Backoff.max_attempts)