2023-01-09 23:16:09 +00:00
|
|
|
from contextlib import asynccontextmanager as acm
|
2023-02-21 15:21:03 +00:00
|
|
|
from functools import partial
|
2019-02-26 01:23:20 +00:00
|
|
|
import os
|
2023-02-26 20:59:55 +00:00
|
|
|
from pathlib import Path
|
2019-02-26 01:23:20 +00:00
|
|
|
|
2018-11-12 02:05:44 +00:00
|
|
|
import pytest
|
2018-11-30 13:18:13 +00:00
|
|
|
import tractor
|
2023-01-09 23:16:09 +00:00
|
|
|
from piker import (
|
|
|
|
config,
|
|
|
|
)
|
2023-03-08 20:14:39 +00:00
|
|
|
from piker.service import (
|
2023-01-24 20:13:24 +00:00
|
|
|
Services,
|
|
|
|
)
|
2023-02-26 20:59:55 +00:00
|
|
|
from piker.clearing._client import open_ems
|
2018-11-30 13:18:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
def pytest_addoption(parser):
|
|
|
|
parser.addoption("--ll", action="store", dest='loglevel',
|
|
|
|
default=None, help="logging level to set when testing")
|
2019-02-26 01:23:20 +00:00
|
|
|
parser.addoption("--confdir", default=None,
|
|
|
|
help="Use a practice API account")
|
2018-11-30 13:18:13 +00:00
|
|
|
|
|
|
|
|
2023-02-21 15:21:03 +00:00
|
|
|
@pytest.fixture(scope='session')
|
|
|
|
def loglevel(request) -> str:
|
|
|
|
return request.config.option.loglevel
|
|
|
|
|
|
|
|
|
2019-02-26 01:23:20 +00:00
|
|
|
@pytest.fixture(scope='session')
|
|
|
|
def test_config():
|
|
|
|
dirname = os.path.dirname
|
|
|
|
dirpath = os.path.abspath(
|
|
|
|
os.path.join(
|
|
|
|
dirname(os.path.realpath(__file__)),
|
|
|
|
'data'
|
|
|
|
)
|
|
|
|
)
|
|
|
|
return dirpath
|
|
|
|
|
|
|
|
|
2019-03-18 03:04:04 +00:00
|
|
|
@pytest.fixture(scope='session', autouse=True)
|
2023-02-21 15:21:03 +00:00
|
|
|
def confdir(
|
|
|
|
request,
|
|
|
|
test_config: str,
|
|
|
|
):
|
2023-01-09 23:16:09 +00:00
|
|
|
'''
|
|
|
|
If the `--confdir` flag is not passed use the
|
2019-03-18 03:04:04 +00:00
|
|
|
broker config file found in that dir.
|
2023-01-09 23:16:09 +00:00
|
|
|
|
|
|
|
'''
|
2019-03-18 03:04:04 +00:00
|
|
|
confdir = request.config.option.confdir
|
|
|
|
if confdir is not None:
|
|
|
|
config._override_config_dir(confdir)
|
|
|
|
|
|
|
|
return confdir
|
|
|
|
|
|
|
|
|
2023-01-09 20:30:26 +00:00
|
|
|
_ci_env: bool = os.environ.get('CI', False)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='session')
|
|
|
|
def ci_env() -> bool:
|
2023-01-09 23:16:09 +00:00
|
|
|
'''
|
|
|
|
Detect CI envoirment.
|
|
|
|
|
|
|
|
'''
|
2023-01-09 20:30:26 +00:00
|
|
|
return _ci_env
|
|
|
|
|
2023-01-09 23:16:09 +00:00
|
|
|
|
|
|
|
@acm
|
|
|
|
async def _open_test_pikerd(
|
2023-03-09 19:33:12 +00:00
|
|
|
tmpconfdir: str,
|
2023-01-09 23:16:09 +00:00
|
|
|
reg_addr: tuple[str, int] | None = None,
|
2023-02-21 14:35:38 +00:00
|
|
|
loglevel: str = 'warning',
|
2023-01-09 23:16:09 +00:00
|
|
|
**kwargs,
|
|
|
|
|
|
|
|
) -> tuple[
|
|
|
|
str,
|
|
|
|
int,
|
|
|
|
tractor.Portal
|
|
|
|
]:
|
|
|
|
'''
|
|
|
|
Testing helper to startup the service tree and runtime on
|
|
|
|
a different port then the default to allow testing alongside
|
|
|
|
a running stack.
|
|
|
|
|
|
|
|
'''
|
|
|
|
import random
|
2023-03-08 20:14:39 +00:00
|
|
|
from piker.service import maybe_open_pikerd
|
2023-01-09 23:16:09 +00:00
|
|
|
|
|
|
|
if reg_addr is None:
|
|
|
|
port = random.randint(6e3, 7e3)
|
|
|
|
reg_addr = ('127.0.0.1', port)
|
|
|
|
|
|
|
|
async with (
|
|
|
|
maybe_open_pikerd(
|
|
|
|
registry_addr=reg_addr,
|
2023-02-21 15:21:03 +00:00
|
|
|
loglevel=loglevel,
|
2023-03-09 19:33:12 +00:00
|
|
|
|
|
|
|
tractor_runtime_overrides={
|
|
|
|
'piker_test_dir': tmpconfdir,
|
|
|
|
},
|
2023-01-09 23:16:09 +00:00
|
|
|
**kwargs,
|
2023-01-24 20:13:24 +00:00
|
|
|
) as service_manager,
|
2023-01-09 23:16:09 +00:00
|
|
|
):
|
2023-01-10 20:40:45 +00:00
|
|
|
# this proc/actor is the pikerd
|
2023-01-24 20:13:24 +00:00
|
|
|
assert service_manager is Services
|
2023-01-10 20:40:45 +00:00
|
|
|
|
2023-01-09 23:16:09 +00:00
|
|
|
async with tractor.wait_for_actor(
|
|
|
|
'pikerd',
|
|
|
|
arbiter_sockaddr=reg_addr,
|
|
|
|
) as portal:
|
|
|
|
raddr = portal.channel.raddr
|
|
|
|
assert raddr == reg_addr
|
|
|
|
yield (
|
|
|
|
raddr[0],
|
|
|
|
raddr[1],
|
|
|
|
portal,
|
2023-01-24 20:13:24 +00:00
|
|
|
service_manager,
|
2023-01-09 23:16:09 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
2023-02-21 15:21:03 +00:00
|
|
|
def open_test_pikerd(
|
2023-03-09 19:33:12 +00:00
|
|
|
request: pytest.FixtureRequest,
|
|
|
|
tmp_path: Path,
|
2023-02-21 15:21:03 +00:00
|
|
|
loglevel: str,
|
|
|
|
):
|
2023-03-09 19:33:12 +00:00
|
|
|
tmpconfdir: Path = tmp_path / '_testing'
|
|
|
|
tmpconfdir.mkdir()
|
|
|
|
tmpconfdir_str: str = str(tmpconfdir)
|
|
|
|
|
|
|
|
# NOTE: on linux the tmp config dir is generally located at:
|
|
|
|
# /tmp/pytest-of-<username>/pytest-<run#>/test_<current_test_name>/
|
|
|
|
# the default `pytest` config ensures that only the last 4 test
|
|
|
|
# suite run's dirs will be persisted, otherwise they are removed:
|
|
|
|
# https://docs.pytest.org/en/6.2.x/tmpdir.html#the-default-base-temporary-directory
|
|
|
|
print(f'CURRENT TEST CONF DIR: {tmpconfdir}')
|
2023-01-09 23:16:09 +00:00
|
|
|
|
2023-02-21 15:21:03 +00:00
|
|
|
yield partial(
|
|
|
|
_open_test_pikerd,
|
|
|
|
|
2023-03-09 19:33:12 +00:00
|
|
|
# pass in a unique temp dir for this test request
|
|
|
|
# so that we can have multiple tests running (maybe in parallel)
|
|
|
|
# bwitout clobbering each other's config state.
|
|
|
|
tmpconfdir=tmpconfdir_str,
|
|
|
|
|
2023-02-21 15:21:03 +00:00
|
|
|
# bind in level from fixture, which is itself set by
|
|
|
|
# `--ll <value>` cli flag.
|
|
|
|
loglevel=loglevel,
|
|
|
|
)
|
2023-01-09 23:16:09 +00:00
|
|
|
|
2023-03-09 19:33:12 +00:00
|
|
|
# NOTE: the `tmp_dir` fixture will wipe any files older then 3 test
|
|
|
|
# sessions by default:
|
|
|
|
# https://docs.pytest.org/en/6.2.x/tmpdir.html#the-default-base-temporary-directory
|
|
|
|
# BUT, if we wanted to always wipe conf dir and all contained files,
|
|
|
|
# rmtree(str(tmp_path))
|
|
|
|
|
2023-01-09 23:16:09 +00:00
|
|
|
# TODO: teardown checks such as,
|
|
|
|
# - no leaked subprocs or shm buffers
|
|
|
|
# - all requested container service are torn down
|
|
|
|
# - certain ``tractor`` runtime state?
|
2023-02-26 20:59:55 +00:00
|
|
|
|
|
|
|
|
|
|
|
@acm
|
|
|
|
async def _open_test_pikerd_and_ems(
|
|
|
|
fqsn,
|
|
|
|
mode,
|
|
|
|
loglevel,
|
|
|
|
open_test_pikerd
|
|
|
|
):
|
|
|
|
async with (
|
|
|
|
open_test_pikerd() as (_, _, _, services),
|
|
|
|
open_ems(
|
|
|
|
fqsn,
|
|
|
|
mode=mode,
|
|
|
|
loglevel=loglevel,
|
2023-03-08 20:14:39 +00:00
|
|
|
) as ems_services,
|
|
|
|
):
|
|
|
|
yield (services, ems_services)
|
2023-02-26 20:59:55 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def open_test_pikerd_and_ems(
|
|
|
|
open_test_pikerd,
|
|
|
|
fqsn: str = 'xbtusdt.kraken',
|
|
|
|
mode: str = 'paper',
|
|
|
|
loglevel: str = 'info',
|
|
|
|
):
|
|
|
|
yield partial(
|
|
|
|
_open_test_pikerd_and_ems,
|
|
|
|
fqsn,
|
|
|
|
mode,
|
|
|
|
loglevel,
|
|
|
|
open_test_pikerd
|
2023-03-08 20:14:39 +00:00
|
|
|
)
|