Add a token refresh test that exhibits an API race issue

kivy_mainline_and_py3.8
Tyler Goodlet 2019-02-04 00:16:16 -05:00
parent 5dac8fa44d
commit 5339f754a1
1 changed files with 51 additions and 4 deletions

View File

@ -2,15 +2,19 @@
Questrade broker testing Questrade broker testing
""" """
import time import time
import logging
import trio import trio
import tractor
from trio.testing import trio_test from trio.testing import trio_test
import tractor
from tractor.testing import tractor_test from tractor.testing import tractor_test
from piker.brokers import questrade as qt from piker.brokers import questrade as qt
import pytest import pytest
log = tractor.get_logger('tests')
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def check_qt_conf_section(brokerconf): def check_qt_conf_section(brokerconf):
"""Skip this module's tests if we have not quetrade API creds. """Skip this module's tests if we have not quetrade API creds.
@ -101,6 +105,49 @@ def match_packet(symbols, quotes, feed_type='stock'):
assert not quotes assert not quotes
async def intermittently_refresh_tokens():
async with qt.get_client() as client:
try:
while True:
try:
log.info("REFRESHING TOKENS!")
await client.ensure_access(force_refresh=True)
await trio.sleep(0.3)
except Exception:
log.exception("Token refresh failed")
finally:
with trio.open_cancel_scope(shield=True):
async with qt.get_client() as client:
await client.ensure_access(force_refresh=True)
# XXX: demonstrates the shoddy API QT serves
@pytest.mark.skip
@tractor_test
async def test_concurrent_tokens_refresh(us_symbols, loglevel):
async with qt.get_client() as client:
# async with tractor.open_nursery() as n:
# await n.run_in_actor('other', intermittently_refresh_tokens)
async with trio.open_nursery() as n:
n.start_soon(intermittently_refresh_tokens)
quoter = await qt.stock_quoter(client, us_symbols)
async def get_quotes():
for tries in range(10):
log.info(f"{tries}: GETTING QUOTES!")
quotes = await quoter(us_symbols)
await trio.sleep(0.1)
await get_quotes()
# shutdown
# await n.cancel()
n.cancel_scope.cancel()
@trio_test @trio_test
async def test_batched_stock_quote(us_symbols): async def test_batched_stock_quote(us_symbols):
"""Use the client stock quote api and verify quote response format. """Use the client stock quote api and verify quote response format.
@ -201,13 +248,13 @@ async def stream_option_chain(portal, symbols):
broker='questrade', broker='questrade',
symbols=[sub], symbols=[sub],
feed_type='option', feed_type='option',
rate=4, rate=3,
diff_cached=False, diff_cached=False,
) )
# latency arithmetic # latency arithmetic
loops = 8 loops = 8
rate = 1/3. # 3 rps period = 1/3. # 3 rps
timeout = loops / rate timeout = loops / period
try: try:
# wait on the data streamer to actually start # wait on the data streamer to actually start