nucypher/tests/unit/test_blockchain_events.py

104 lines
3.4 KiB
Python

from unittest.mock import MagicMock, Mock
import pytest
from nucypher.blockchain.eth.events import ContractEventsThrottler
def test_contract_events_throttler_to_block_check():
event_name = 'TestEvent'
latest_block = 50
blockchain = MagicMock()
blockchain.client.block_number = latest_block
agent = Mock(events={event_name: Mock(return_value=[])}, blockchain=blockchain)
# from_block < to_block
throttler = ContractEventsThrottler(agent=agent, event_name=event_name, from_block=1, to_block=10)
assert throttler.from_block == 1
assert throttler.to_block == 10
# to_block < from_block
with pytest.raises(ValueError):
ContractEventsThrottler(agent=agent, event_name=event_name, from_block=10, to_block=8)
# to_block can be equal to from_block
throttler = ContractEventsThrottler(agent=agent, event_name=event_name, from_block=10, to_block=10)
assert throttler.from_block == 10
assert throttler.to_block == 10
# from_block and to_block value of zero allowed
throttler = ContractEventsThrottler(agent=agent, event_name=event_name, from_block=0, to_block=0)
assert throttler.from_block == 0
assert throttler.to_block == 0
#
# when to_block is not specified it defaults to latest block number
#
# latest block is lower than from_block
with pytest.raises(ValueError):
ContractEventsThrottler(agent=agent, event_name=event_name, from_block=latest_block + 1)
# latest block is equal to from_block
throttler = ContractEventsThrottler(agent=agent, event_name=event_name, from_block=latest_block)
assert throttler.from_block == latest_block
assert throttler.to_block == latest_block
def test_contract_events_throttler_inclusive_block_ranges():
event_name = 'TestEvent'
#
# 1 block at a time
#
mock_method = Mock(return_value=[])
agent = Mock(events={event_name: mock_method})
events_throttler = ContractEventsThrottler(
agent=agent,
event_name=event_name,
from_block=0,
to_block=10,
max_blocks_per_call=1
)
for _ in events_throttler:
pass
# check calls to filter
# ranges used = (0, 1), (2, 3), (4, 5), (6, 7), (8, 9), (10, 10)
assert mock_method.call_count == 6
mock_method.assert_any_call(from_block=0, to_block=1)
mock_method.assert_any_call(from_block=2, to_block=3)
mock_method.assert_any_call(from_block=4, to_block=5)
mock_method.assert_any_call(from_block=6, to_block=7)
mock_method.assert_any_call(from_block=8, to_block=9)
mock_method.assert_any_call(from_block=10, to_block=10)
#
# 5 blocks at a time
#
mock_method = Mock(return_value=[])
agent = Mock(events={event_name: mock_method})
argument_filters = {'address': '0xdeadbeef'}
events_throttler = ContractEventsThrottler(
agent=agent,
event_name=event_name,
from_block=0,
to_block=21,
max_blocks_per_call=5,
**argument_filters
)
for _ in events_throttler:
pass
# check calls to filter
# ranges used = (0, 5), (6, 11), (12, 17) (18, 21)
assert mock_method.call_count == 4
mock_method.assert_any_call(**argument_filters, from_block=0, to_block=5)
mock_method.assert_any_call(**argument_filters, from_block=6, to_block=11)
mock_method.assert_any_call(**argument_filters, from_block=12, to_block=17)
mock_method.assert_any_call(**argument_filters, from_block=18, to_block=21)