Skip to content

Commit

Permalink
skip broken test on dynalite, allow pytest-xdist
Browse files Browse the repository at this point in the history
  • Loading branch information
ojii committed Jul 13, 2024
1 parent 05f6707 commit 03fc56b
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
implementation: [
{flavor: "other", name: "dynalite"},
{flavor: "dynalite", name: "dynalite"},
{flavor: "other", name: "dynamodb-local"},
{flavor: "other", name: "localstack"},
{flavor: "scylla", name: "scylla"}
Expand Down
6 changes: 3 additions & 3 deletions docs/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Please ensure you have `pre-commit`_ set up so that code formatting is applied a
Tests
-----

To run the tests run ``poetry run pytest``.
To run the tests run ``poetry run pytest``. On most systems ``poetry run pytest --numprocesses auto`` will lead to a much faster execution of the test suite.

Integration Tests
-----------------
Expand All @@ -22,9 +22,9 @@ Alternative DynamoDB Implementations

Currently, aiodynamo is tested with `dynamodb-local`_, `dynalite`_ and `ScyllaDB Alternator`_.

To test with one or more implementations, set the ``DYNAMODB_URLS`` environment variable. The value of that variable should be a space separated list of ``<name>=<config>`` pairs, where ``<config>`` is ``<url>[,<flavor>]`` with ``<flavor>`` being one of ``real``, ``scylla`` or ``other``. The flavor must be set for `ScyllaDB Alternator`_ as it has a slightly different behavior in ``DescribeTable`` compared to other implementations.
To test with one or more implementations, set the ``DYNAMODB_URLS`` environment variable. The value of that variable should be a space separated list of ``<name>=<config>`` pairs, where ``<config>`` is ``<url>[,<flavor>]`` with ``<flavor>`` being one of ``real``, ``dynalite``, ``scylla`` or ``other``. The flavor must be set for `ScyllaDB Alternator`_ as it has a slightly different behavior in ``DescribeTable`` compared to other implementations and `dynalite`_ as it has some known issues.

For example, to run the tests for all three instances with `dynamodb-local`_ running on port 8001, `dynalite`_ running on port 8002 and `ScyllaDB Alternator`_ running on port 8003, you would set ``DYNAMODB_URLS='dynamodb-local=http://localhost:8001 dynalite=http://localhost:8002 scylla=http://localhost:8003,scylla'``
For example, to run the tests for all three instances with `dynamodb-local`_ running on port 8001, `dynalite`_ running on port 8002 and `ScyllaDB Alternator`_ running on port 8003, you would set ``DYNAMODB_URLS='dynamodb-local=http://localhost:8001 dynalite=http://localhost:8002,dynalite scylla=http://localhost:8003,scylla'``

Since these alternative implementations still require credentials to be set, set both ``AWS_ACCESS_KEY_ID`` and ``AWS_SECRET_ACCESS_KEY`` to some made up value.

Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ httpx = ["httpx"]
aiohttp = ["aiohttp"]

[tool.poetry.group.dev.dependencies]
pytest = "^6.0"
pytest = "^7.0"
pytest-asyncio = "^0.17"
pytest-cov = "^2.6"
black = "^22.3"
Expand All @@ -49,6 +49,7 @@ furo = "^2023.9.10"
ruff = "^0.0.292"
httpx = ">=0.15.0 <1.0.0"
aiohttp = "^3.6.2"
pytest-xdist = "^3.6.1"

[tool.pytest.ini_options]
asyncio_mode = "auto"
Expand Down
19 changes: 15 additions & 4 deletions tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
class Flavor(Enum):
real = "real"
scylla = "scylla"
dynalite = "dynalite"
other = "other"


Expand Down Expand Up @@ -94,13 +95,23 @@ def table_name_prefix() -> str:


@pytest.fixture(scope="session")
def real_dynamo(dynamodb_implementation: Implementation) -> bool:
return dynamodb_implementation.flavor is Flavor.real
def flavor(dynamodb_implementation: Implementation) -> Flavor:
return dynamodb_implementation.flavor


@pytest.fixture(scope="session")
def scylla(dynamodb_implementation: Implementation) -> bool:
return dynamodb_implementation.flavor is Flavor.scylla
def real_dynamo(flavor: Flavor) -> bool:
return flavor is Flavor.real


@pytest.fixture(scope="session")
def scylla(flavor: Flavor) -> bool:
return flavor is Flavor.scylla


@pytest.fixture(scope="session")
def dynalite(flavor: Flavor) -> bool:
return flavor is Flavor.dynalite


@pytest.fixture()
Expand Down
11 changes: 10 additions & 1 deletion tests/integration/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,17 @@ async def test_update_item(client: Client, table: TableName) -> None:
ids=repr,
)
async def test_update_item_condition(
client: Client, table: TableName, check: Any, cond: Condition, ok: bool
client: Client,
table: TableName,
check: Any,
cond: Condition,
ok: bool,
dynalite: bool,
) -> None:
if dynalite:
pytest.xfail(
"IN condition known to be broken on dynalite: https://github.com/architect/dynalite/pull/159"
)
key = {"h": "hkv", "r": "rkv"}
item = {**key, "target": 1, "check": check}
await client.put_item(table, item)
Expand Down
38 changes: 34 additions & 4 deletions tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,49 @@ def test_binary_decode() -> None:
}


class XDistReprFix:
"""
This wrapper is needed because some types, such as
`DYNAMODB_CONTEXT.create_decimal` cannot be used in
`pytest.mark.parametrize` because they do not have a
stable `__repr__` (the `__repr__` includes the objects
id which is different in each process), causing
non-deterministic test case order, which pytest-xdist
rejects.
"""

def __init__(self, ntc: NumericTypeConverter) -> None:
self.ntc = ntc
self.name = ntc.__name__

def __repr__(self) -> str:
return self.name

def __call__(self, value: str) -> Any:
return self.ntc(value)


@pytest.mark.parametrize(
"value,numeric_type,result",
[
(
{
"N": "1.2",
},
float,
XDistReprFix(float),
1.2,
),
({"NS": ["1.2"]}, float, {1.2}),
({"N": "1.2"}, DYNAMODB_CONTEXT.create_decimal, Decimal("1.2")),
({"NS": ["1.2"]}, DYNAMODB_CONTEXT.create_decimal, {Decimal("1.2")}),
({"NS": ["1.2"]}, XDistReprFix(float), {1.2}),
(
{"N": "1.2"},
XDistReprFix(DYNAMODB_CONTEXT.create_decimal),
Decimal("1.2"),
),
(
{"NS": ["1.2"]},
XDistReprFix(DYNAMODB_CONTEXT.create_decimal),
{Decimal("1.2")},
),
],
)
def test_numeric_decode(
Expand Down

0 comments on commit 03fc56b

Please sign in to comment.