def test_wait_log_predicate(get_log): def pred(): raise PredicateNotSatisfied('bad attempt') with pytest.raises(TimeoutException): wait(pred=pred, timeout=.5, sleep=.1, message=False, log_interval=0.2) durations = re.findall('Still waiting after (.*?): bad attempt', get_log()) rounded_durations = [round(Duration(d), 2) for d in durations] assert rounded_durations == [ 0.2, 0.4 ], 'expected logs at 200ms and 400ms, got %s' % (durations, )
def test_timeout_exception(): exc = None with timing() as t: try: wait(0.5, lambda: False, message=False) except TimeoutException as e: exc = e assert exc.duration > 0.5 assert exc.start_time >= t.start_time assert exc.start_time < t.stop_time assert t.duration > exc.duration
def test_wait_with_callable_message(): val = ['FOO'] with pytest.raises(TimeoutException) as e: def pred(): val[0] = 'BAR' return False wait(pred=pred, timeout=.1, message=lambda: 'val is %s' % val[0]) assert val[0] == 'BAR' assert e.value.message == 'val is BAR'
def test_wait_exception(): with pytest.raises(Exception, match=".*`message` is required.*"): wait(0.1, pred=lambda: True) wait(0.1) wait(0.1, pred=lambda: True, message='message') wait(0.1, pred=lambda: True, message=False) repeat(0.1, callback=lambda: True)
def test_wait_long_predicate(): """ After the actual check the predicate is held for .3 seconds. Make sure that we don't get a timeout after .2 seconds - because the actual condition should be met in .1 second! """ t = Timer() def pred(): try: return 0.1 < t.duration finally: wait(0.3) wait(0.2, pred, message=False)
def test_wait_do_something_on_final_attempt(multipred): data = [] def pred(is_final_attempt): if is_final_attempt: data.append('final') data.append('regular') return False if multipred: pred = [pred] with pytest.raises(TimeoutException): wait(pred=pred, timeout=.5, sleep=.1, message=False) assert all(iteration == 'regular' for iteration in data[:-2]) assert data[-2] == 'final' assert data[-1] == 'regular'
def test_wait_better_exception(): class TimedOut(PredicateNotSatisfied): pass i = 0 def check(): nonlocal i i += 1 if i < 3: raise TimedOut(a=1, b=2) return True with pytest.raises(TimedOut): # due to the short timeout and long sleep, the pred would called exactly twice wait(.1, pred=check, sleep=1, message=False) assert i == 2 wait(.1, pred=check, message=False)
def test_wait_better_exception_nested(): class TimedOut(PredicateNotSatisfied): pass i = 0 def check(): nonlocal i i += 1 if i < 3: raise TimedOut(a=1, b=2) return True with pytest.raises(TimedOut): # due to the short timeout and long sleep, the pred would called exactly twice # also, the external wait should call the inner one only once, due to the TimedOut exception, # which it knows not to swallow wait(5, lambda: wait(.1, pred=check, sleep=1, message=False), sleep=1, message=False) assert i == 2 wait(.1, pred=check, message=False)
def pred(): try: return 0.1 < t.duration finally: wait(0.3)