1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
from __future__ import print_function
import itertools
import time
import pytest
import mock
import six
import irc.client
def test_version():
assert 'VERSION' in vars(irc.client)
assert 'VERSION_STRING' in vars(irc.client)
assert isinstance(irc.client.VERSION, tuple)
assert irc.client.VERSION, "No VERSION detected."
assert isinstance(irc.client.VERSION_STRING, six.string_types)
@mock.patch('irc.connection.socket')
def test_privmsg_sends_msg(socket_mod):
server = irc.client.IRC().server()
server.connect('foo', 6667, 'bestnick')
# make sure the mock object doesn't have a write method or it will treat
# it as an SSL connection and never call .send.
del server.socket.write
server.privmsg('#best-channel', 'You are great')
server.socket.send.assert_called_with(
b'PRIVMSG #best-channel :You are great\r\n')
@mock.patch('irc.connection.socket')
def test_privmsg_fails_on_embedded_carriage_returns(socket_mod):
server = irc.client.IRC().server()
server.connect('foo', 6667, 'bestnick')
with pytest.raises(ValueError):
server.privmsg('#best-channel', 'You are great\nSo are you')
class TestHandlers(object):
def test_handlers_same_priority(self):
"""
Two handlers of the same priority should still compare.
"""
handler1 = irc.client.PrioritizedHandler(1, lambda: None)
handler2 = irc.client.PrioritizedHandler(1, lambda: 'other')
assert not handler1 < handler2
assert not handler2 < handler1
class FakeClock(object):
""" A fake clock that is under control of test cases. """
_default_initial_seconds = 1450000000.0
_default_tick_duration = 0.0005
def __init__(
self,
seconds=_default_initial_seconds,
tick_duration=_default_tick_duration,
):
self._tick_duration = tick_duration
self.reset(seconds)
def reset(self, seconds):
""" Reset the clock time to `seconds`. """
self._seconds = seconds
def advance(self, seconds):
""" Advance the clock by `seconds`. """
self._seconds += max(0, seconds)
def tick(self):
""" Advance the clock by its tick duration. """
self.advance(self._tick_duration)
def time(self):
""" Get the current time, as seconds since epoch. """
self.tick()
return self._seconds
fake_clock = FakeClock()
@mock.patch.object(time, 'time', new=fake_clock.time)
@mock.patch.object(time, 'sleep', new=fake_clock.advance)
class TestThrottler(object):
def test_function_throttled(self):
"""
Ensure the throttler actually throttles calls.
"""
# set up a function to be called
counter = itertools.count()
# set up a version of `next` that is only called 30 times per second
limited_next = irc.client.Throttler(next, 30)
# for one second, call next as fast as possible
deadline = time.time() + 1
while time.time() < deadline:
limited_next(counter)
# ensure the counter was advanced about 30 times
assert 29 <= next(counter) <= 32
# ensure that another burst of calls after some idle period will also
# get throttled
time.sleep(1)
deadline = time.time() + 1
counter = itertools.count()
while time.time() < deadline:
limited_next(counter)
assert 29 <= next(counter) <= 32
def test_reconstruct_unwraps(self):
"""
The throttler should be re-usable - if one wants to throttle a
function that's aready throttled, the original function should be
used.
"""
wrapped = irc.client.Throttler(next, 30)
wrapped_again = irc.client.Throttler(wrapped, 60)
assert wrapped_again.func is next
assert wrapped_again.max_rate == 60
|