diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..1d17dae --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +.venv diff --git a/.gitignore b/.gitignore index 809143c..427273d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,141 @@ -build -*.o -*.pyc -tmp -*.log -*.tmp +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ .tox/ -.idea/ -dist -*.egg-info +.nox/ .coverage -htmlcov/ +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# rethinkdb binary +server/ diff --git a/Pipfile b/Pipfile index f976548..63d9dac 100644 --- a/Pipfile +++ b/Pipfile @@ -22,5 +22,7 @@ python_version = "3" [scripts] test = "pytest --cov rethinkdb_mock -vv" +test_live = "pytest --cov rethinkdb_mock -vv -x --run rethink" +last_live = "pytest --cov rethinkdb_mock -vv -x --run rethink --last-failed" isort = "isort ." lint = "flake8 ." diff --git a/Pipfile.lock b/Pipfile.lock index b876591..b35a224 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "d87d4d8ec9c9864309d9baef9d8c3e0a2892806a4ee2c13b5e07cf7b54966ff9" + "sha256": "030a2f5a93d25541f988b15f687a6a2a791901cd975461992b45ee9e7d6f7b05" }, "pipfile-spec": 6, "requires": { - "python_version": "3.9" + "python_version": "3" }, "sources": [ { @@ -113,58 +113,58 @@ }, "coverage": { "hashes": [ - "sha256:08b3ba72bd981531fd557f67beee376d6700fba183b167857038997ba30dd297", - "sha256:2757fa64e11ec12220968f65d086b7a29b6583d16e9a544c889b22ba98555ef1", - "sha256:3102bb2c206700a7d28181dbe04d66b30780cde1d1c02c5f3c165cf3d2489497", - "sha256:3498b27d8236057def41de3585f317abae235dd3a11d33e01736ffedb2ef8606", - "sha256:378ac77af41350a8c6b8801a66021b52da8a05fd77e578b7380e876c0ce4f528", - "sha256:38f16b1317b8dd82df67ed5daa5f5e7c959e46579840d77a67a4ceb9cef0a50b", - "sha256:3911c2ef96e5ddc748a3c8b4702c61986628bb719b8378bf1e4a6184bbd48fe4", - "sha256:3a3c3f8863255f3c31db3889f8055989527173ef6192a283eb6f4db3c579d830", - "sha256:3b14b1da110ea50c8bcbadc3b82c3933974dbeea1832e814aab93ca1163cd4c1", - "sha256:535dc1e6e68fad5355f9984d5637c33badbdc987b0c0d303ee95a6c979c9516f", - "sha256:6f61319e33222591f885c598e3e24f6a4be3533c1d70c19e0dc59e83a71ce27d", - "sha256:723d22d324e7997a651478e9c5a3120a0ecbc9a7e94071f7e1954562a8806cf3", - "sha256:76b2775dda7e78680d688daabcb485dc87cf5e3184a0b3e012e1d40e38527cc8", - "sha256:782a5c7df9f91979a7a21792e09b34a658058896628217ae6362088b123c8500", - "sha256:7e4d159021c2029b958b2363abec4a11db0ce8cd43abb0d9ce44284cb97217e7", - "sha256:8dacc4073c359f40fcf73aede8428c35f84639baad7e1b46fce5ab7a8a7be4bb", - "sha256:8f33d1156241c43755137288dea619105477961cfa7e47f48dbf96bc2c30720b", - "sha256:8ffd4b204d7de77b5dd558cdff986a8274796a1e57813ed005b33fd97e29f059", - "sha256:93a280c9eb736a0dcca19296f3c30c720cb41a71b1f9e617f341f0a8e791a69b", - "sha256:9a4f66259bdd6964d8cf26142733c81fb562252db74ea367d9beb4f815478e72", - "sha256:9a9d4ff06804920388aab69c5ea8a77525cf165356db70131616acd269e19b36", - "sha256:a2070c5affdb3a5e751f24208c5c4f3d5f008fa04d28731416e023c93b275277", - "sha256:a4857f7e2bc6921dbd487c5c88b84f5633de3e7d416c4dc0bb70256775551a6c", - "sha256:a607ae05b6c96057ba86c811d9c43423f35e03874ffb03fbdcd45e0637e8b631", - "sha256:a66ca3bdf21c653e47f726ca57f46ba7fc1f260ad99ba783acc3e58e3ebdb9ff", - "sha256:ab110c48bc3d97b4d19af41865e14531f300b482da21783fdaacd159251890e8", - "sha256:b239711e774c8eb910e9b1ac719f02f5ae4bf35fa0420f438cdc3a7e4e7dd6ec", - "sha256:be0416074d7f253865bb67630cf7210cbc14eb05f4099cc0f82430135aaa7a3b", - "sha256:c46643970dff9f5c976c6512fd35768c4a3819f01f61169d8cdac3f9290903b7", - "sha256:c5ec71fd4a43b6d84ddb88c1df94572479d9a26ef3f150cef3dacefecf888105", - "sha256:c6e5174f8ca585755988bc278c8bb5d02d9dc2e971591ef4a1baabdf2d99589b", - "sha256:c89b558f8a9a5a6f2cfc923c304d49f0ce629c3bd85cb442ca258ec20366394c", - "sha256:cc44e3545d908ecf3e5773266c487ad1877be718d9dc65fc7eb6e7d14960985b", - "sha256:cc6f8246e74dd210d7e2b56c76ceaba1cc52b025cd75dbe96eb48791e0250e98", - "sha256:cd556c79ad665faeae28020a0ab3bda6cd47d94bec48e36970719b0b86e4dcf4", - "sha256:ce6f3a147b4b1a8b09aae48517ae91139b1b010c5f36423fa2b866a8b23df879", - "sha256:ceb499d2b3d1d7b7ba23abe8bf26df5f06ba8c71127f188333dddcf356b4b63f", - "sha256:cef06fb382557f66d81d804230c11ab292d94b840b3cb7bf4450778377b592f4", - "sha256:e448f56cfeae7b1b3b5bcd99bb377cde7c4eb1970a525c770720a352bc4c8044", - "sha256:e52d3d95df81c8f6b2a1685aabffadf2d2d9ad97203a40f8d61e51b70f191e4e", - "sha256:ee2f1d1c223c3d2c24e3afbb2dd38be3f03b1a8d6a83ee3d9eb8c36a52bee899", - "sha256:f2c6888eada180814b8583c3e793f3f343a692fc802546eed45f40a001b1169f", - "sha256:f51dbba78d68a44e99d484ca8c8f604f17e957c1ca09c3ebc2c7e3bbd9ba0448", - "sha256:f54de00baf200b4539a5a092a759f000b5f45fd226d6d25a76b0dff71177a714", - "sha256:fa10fee7e32213f5c7b0d6428ea92e3a3fdd6d725590238a3f92c0de1c78b9d2", - "sha256:fabeeb121735d47d8eab8671b6b031ce08514c86b7ad8f7d5490a7b6dcd6267d", - "sha256:fac3c432851038b3e6afe086f777732bcf7f6ebbfd90951fa04ee53db6d0bcdd", - "sha256:fda29412a66099af6d6de0baa6bd7c52674de177ec2ad2630ca264142d69c6c7", - "sha256:ff1330e8bc996570221b450e2d539134baa9465f5cb98aff0e0f73f34172e0ae" + "sha256:03ed2a641e412e42cc35c244508cf186015c217f0e4d496bf6d7078ebe837ae7", + "sha256:04b14e45d6a8e159c9767ae57ecb34563ad93440fc1b26516a89ceb5b33c1ad5", + "sha256:0cdde51bfcf6b6bd862ee9be324521ec619b20590787d1655d005c3fb175005f", + "sha256:0f48fc7dc82ee14aeaedb986e175a429d24129b7eada1b7e94a864e4f0644dde", + "sha256:107d327071061fd4f4a2587d14c389a27e4e5c93c7cba5f1f59987181903902f", + "sha256:1375bb8b88cb050a2d4e0da901001347a44302aeadb8ceb4b6e5aa373b8ea68f", + "sha256:14a9f1887591684fb59fdba8feef7123a0da2424b0652e1b58dd5b9a7bb1188c", + "sha256:16baa799ec09cc0dcb43a10680573269d407c159325972dd7114ee7649e56c66", + "sha256:1b811662ecf72eb2d08872731636aee6559cae21862c36f74703be727b45df90", + "sha256:1ccae21a076d3d5f471700f6d30eb486da1626c380b23c70ae32ab823e453337", + "sha256:2f2cf7a42d4b7654c9a67b9d091ec24374f7c58794858bff632a2039cb15984d", + "sha256:322549b880b2d746a7672bf6ff9ed3f895e9c9f108b714e7360292aa5c5d7cf4", + "sha256:32ab83016c24c5cf3db2943286b85b0a172dae08c58d0f53875235219b676409", + "sha256:3fe50f1cac369b02d34ad904dfe0771acc483f82a1b54c5e93632916ba847b37", + "sha256:4a780807e80479f281d47ee4af2eb2df3e4ccf4723484f77da0bb49d027e40a1", + "sha256:4a8eb7785bd23565b542b01fb39115a975fefb4a82f23d407503eee2c0106247", + "sha256:5bee3970617b3d74759b2d2df2f6a327d372f9732f9ccbf03fa591b5f7581e39", + "sha256:60a3307a84ec60578accd35d7f0c71a3a971430ed7eca6567399d2b50ef37b8c", + "sha256:6625e52b6f346a283c3d563d1fd8bae8956daafc64bb5bbd2b8f8a07608e3994", + "sha256:66a5aae8233d766a877c5ef293ec5ab9520929c2578fd2069308a98b7374ea8c", + "sha256:68fb816a5dd901c6aff352ce49e2a0ffadacdf9b6fae282a69e7a16a02dad5fb", + "sha256:6b588b5cf51dc0fd1c9e19f622457cc74b7d26fe295432e434525f1c0fae02bc", + "sha256:6c4d7165a4e8f41eca6b990c12ee7f44fef3932fac48ca32cecb3a1b2223c21f", + "sha256:6d2e262e5e8da6fa56e774fb8e2643417351427604c2b177f8e8c5f75fc928ca", + "sha256:6d9c88b787638a451f41f97446a1c9fd416e669b4d9717ae4615bd29de1ac135", + "sha256:755c56beeacac6a24c8e1074f89f34f4373abce8b662470d3aa719ae304931f3", + "sha256:7e40d3f8eb472c1509b12ac2a7e24158ec352fc8567b77ab02c0db053927e339", + "sha256:812eaf4939ef2284d29653bcfee9665f11f013724f07258928f849a2306ea9f9", + "sha256:84df004223fd0550d0ea7a37882e5c889f3c6d45535c639ce9802293b39cd5c9", + "sha256:859f0add98707b182b4867359e12bde806b82483fb12a9ae868a77880fc3b7af", + "sha256:87c4b38288f71acd2106f5d94f575bc2136ea2887fdb5dfe18003c881fa6b370", + "sha256:89fc12c6371bf963809abc46cced4a01ca4f99cba17be5e7d416ed7ef1245d19", + "sha256:9564ac7eb1652c3701ac691ca72934dd3009997c81266807aef924012df2f4b3", + "sha256:9754a5c265f991317de2bac0c70a746efc2b695cf4d49f5d2cddeac36544fb44", + "sha256:a565f48c4aae72d1d3d3f8e8fb7218f5609c964e9c6f68604608e5958b9c60c3", + "sha256:a636160680c6e526b84f85d304e2f0bb4e94f8284dd765a1911de9a40450b10a", + "sha256:a839e25f07e428a87d17d857d9935dd743130e77ff46524abb992b962eb2076c", + "sha256:b62046592b44263fa7570f1117d372ae3f310222af1fc1407416f037fb3af21b", + "sha256:b7f7421841f8db443855d2854e25914a79a1ff48ae92f70d0a5c2f8907ab98c9", + "sha256:ba7ca81b6d60a9f7a0b4b4e175dcc38e8fef4992673d9d6e6879fd6de00dd9b8", + "sha256:bb32ca14b4d04e172c541c69eec5f385f9a075b38fb22d765d8b0ce3af3a0c22", + "sha256:c0ff1c1b4d13e2240821ef23c1efb1f009207cb3f56e16986f713c2b0e7cd37f", + "sha256:c669b440ce46ae3abe9b2d44a913b5fd86bb19eb14a8701e88e3918902ecd345", + "sha256:c67734cff78383a1f23ceba3b3239c7deefc62ac2b05fa6a47bcd565771e5880", + "sha256:c6809ebcbf6c1049002b9ac09c127ae43929042ec1f1dbd8bb1615f7cd9f70a0", + "sha256:cd601187476c6bed26a0398353212684c427e10a903aeafa6da40c63309d438b", + "sha256:ebfa374067af240d079ef97b8064478f3bf71038b78b017eb6ec93ede1b6bcec", + "sha256:fbb17c0d0822684b7d6c09915677a32319f16ff1115df5ec05bdcaaee40b35f3", + "sha256:fff1f3a586246110f34dc762098b5afd2de88de507559e63553d7da643053786" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", - "version": "==5.3.1" + "version": "==5.4" }, "decorator": { "hashes": [ @@ -175,11 +175,11 @@ }, "execnet": { "hashes": [ - "sha256:cacb9df31c9680ec5f95553976c4da484d407e85e41c83cb812aa014f0eddc50", - "sha256:d4efd397930c46415f62f8a31388d6be4f27a91d7550eb79bc64a756e0056547" + "sha256:7a13113028b1e1cc4c6492b28098b3c6576c9dccc7973bfe47b342afadafb2ac", + "sha256:b73c5565e517f24b62dea8a5ceac178c661c4309d3aa0c3e420856c072c411b4" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.7.1" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==1.8.0" }, "flake8": { "hashes": [ @@ -342,19 +342,19 @@ }, "pytest": { "hashes": [ - "sha256:1969f797a1a0dbd8ccf0fecc80262312729afea9c17f1d70ebf85c5e76c6f7c8", - "sha256:66e419b1899bc27346cb2c993e12c5e5e8daba9073c1fbce33b9807abc95c306" + "sha256:9d1edf9e7d0b84d72ea3dbcdfd22b35fb543a5e8f2a60092dd578936bf63d7f9", + "sha256:b574b57423e818210672e07ca1fa90aaf194a4f63f3ab909a2c67ebb22913839" ], "index": "pypi", - "version": "==6.2.1" + "version": "==6.2.2" }, "pytest-cov": { "hashes": [ - "sha256:626a8a6ab188656c4f84b67d22436d6c494699d917e567e0048dda6e7f59e028", - "sha256:e90e034cde61dacb1394639a33f449725c591025b182d69752c1dd0bfec639a7" + "sha256:359952d9d39b9f822d9d29324483e7ba04a3a17dd7d05aa6beb7ea01e359e5f7", + "sha256:bdb9fdb0b85a7cc825269a4c56b48ccaa5c7e365054b6038772c32ddcdc969da" ], "index": "pypi", - "version": "==2.11.0" + "version": "==2.11.1" }, "pytest-fixture-config": { "hashes": [ @@ -430,11 +430,11 @@ }, "urllib3": { "hashes": [ - "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08", - "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473" + "sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80", + "sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", - "version": "==1.26.2" + "version": "==1.26.3" } } } diff --git a/README.md b/README.md index 1686b4f..2d8050c 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,16 @@ pipenv sync --dev pipenv run test ``` +### Run tests against a live server + +The docker folder contains a dockerfile that grabs rethinkdb and runs the python tests + +Simple running the below command outputs the results + +```bash +docker-compose up --build +``` + ## Code formatting The `tox.ini` file contains the configuration for code formatting diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..d6803e9 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,9 @@ +version: "3.7" +services: + python: + image: rethinkdb-mock + build: + context: . + dockerfile: docker/test_live.Dockerfile + container_name: integration-test + command: ["pipenv", "run", "test_live"] diff --git a/docker/test_live.Dockerfile b/docker/test_live.Dockerfile new file mode 100644 index 0000000..5e8d4c8 --- /dev/null +++ b/docker/test_live.Dockerfile @@ -0,0 +1,26 @@ +FROM rethinkdb:2.4.1-buster-slim as rdb + +FROM python:3.9-slim-buster + +RUN apt update && apt install -y \ + libcurl4-openssl-dev \ + libprotobuf-dev +# build-essential \ +# protobuf-compiler\ +# libboost-all-dev \ +# libncurses5-dev \ +# libjemalloc-dev \ +# wget m4 + +COPY --from=rdb /usr/bin/rethinkdb /usr/bin/rethinkdb + +RUN mkdir -p /app +COPY . /app +WORKDIR /app + +RUN which rethinkdb + +RUN pip install pipenv +RUN pipenv install --dev --system --deploy + +CMD ["pipenv", "run", "test_live"] diff --git a/tests/conftest.py b/tests/conftest.py index 0d5451a..ef2671f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,10 +1,10 @@ import logging import pytest -from pytest_server_fixtures.rethink import rethink_server_sess import rethinkdb from tests.common import as_db_and_table from tests.common import load_stock_data +from tests.fixtures import _rethink_server from rethinkdb_mock import MockThink @@ -28,7 +28,7 @@ def conn_sess(request): conn_type = cfg.getvalue("conn_type") if conn_type == "rethink": try: - server = rethink_server_sess(request) + server = _rethink_server(request) conn = server.conn except rethinkdb.errors.ReqlDriverError: pytest.exit("Unable to connect to rethink") diff --git a/tests/fixtures.py b/tests/fixtures.py new file mode 100644 index 0000000..0fb424a --- /dev/null +++ b/tests/fixtures.py @@ -0,0 +1,203 @@ +# MIT License + +# Copyright (c) 2016 Man AHL + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +################################################################################ +# The following code is taken from https://github.com/man-group/pytest-plugins # +# and adapted to be compatible with Rethinkdb Python Client 2.4.8 # +################################################################################ + +import logging +import uuid + +import pytest +from pytest_fixture_config import requires_config +from pytest_server_fixtures import CONFIG +from pytest_server_fixtures.base2 import TestServerV2 + +log = logging.getLogger(__name__) +rethinkdb = None + + +def _rethink_server(request): + """ This does the actual work - there are several versions of this used + with different scopes. + """ + test_server = RethinkDBServer() + request.addfinalizer(lambda p=test_server: p.teardown()) + test_server.start() + return test_server + + +@pytest.fixture(scope='function') +@requires_config(CONFIG, ['rethink_executable']) +def rethink_server(request): + """ Function-scoped RethinkDB server in a local thread. + + Attributes + ---------- + conn: (``rethinkdb.Connection``) Connection to this server instance + .. also inherits all attributes from the `workspace` fixture + + """ + return _rethink_server(request) + + +@pytest.fixture(scope='session') +@requires_config(CONFIG, ['rethink_executable']) +def rethink_server_sess(request): + """ Same as rethink_server fixture, scoped as session instead. + """ + return _rethink_server(request) + + +@pytest.yield_fixture(scope="function") +def rethink_unique_db(rethink_server_sess): + """ Starts up a session-scoped server, and returns a connection to + a unique database for the life of a single test, and drops it after + """ + dbid = uuid.uuid4().hex + conn = rethink_server_sess.conn + r.db_create(dbid).run(conn) + conn.use(dbid) + yield conn + r.db_drop(dbid).run(conn) + + +@pytest.yield_fixture(scope="module") +def rethink_module_db(rethink_server_sess): + """ Starts up a module-scoped server, and returns a connection to + a unique database for all the tests in one module. + Drops the database after module tests are complete. + """ + dbid = uuid.uuid4().hex + conn = rethink_server_sess.conn + log.info("Making database") + r.db_create(dbid).run(conn) + conn.use(dbid) + yield conn + log.info("Dropping database") + r.db_drop(dbid).run(conn) + + +@pytest.fixture(scope="module") +def rethink_make_tables(request, rethink_module_db): + """ Module-scoped fixture that creates all tables specified in the test + module attribute FIXTURE_TABLES. + + """ + reqd_table_list = getattr(request.module, 'FIXTURE_TABLES') + log.debug("Do stuff before all module tests with {0}".format(reqd_table_list)) + conn = rethink_module_db + for table_name, primary_key in reqd_table_list: + try: + r.db(conn.db).table_create(table_name, primary_key=primary_key,).run(conn) + log.info('Made table "{0}" with key "{1}"'.format(table_name, primary_key)) + except rethinkdb.errors.RqlRuntimeError as err: + log.debug('Table "{0}" not made: {1}'.format(table_name, err.message)) + + +@pytest.yield_fixture(scope="function") +def rethink_empty_db(request, rethink_module_db, rethink_make_tables): + """ Function-scoped fixture that will empty all the tables defined + for the `rethink_make_tables` fixture. + + This is a useful approach, because of the long time taken to + create a new RethinkDB table, compared to the time to empty one. + """ + tables_to_emptied = ( + table[0] for table in getattr(request.module, 'FIXTURE_TABLES') + ) + conn = rethink_module_db + + for table_name in tables_to_emptied: + rethinkdb.db(conn.db).table(table_name).delete().run(conn) + log.debug('Emptied "{0}" before test'.format(table_name)) + yield conn + + +class RethinkDBServer(TestServerV2): + random_hostname = False + + def __init__(self, **kwargs): + # defer loading of rethinkdb + global r + global rethinkdb + import rethinkdb + from rethinkdb import r + + super(RethinkDBServer, self).__init__(**kwargs) + self._driver_port = self._get_port(28015) + self._cluster_port = self._get_port(29015) + self._http_port = self._get_port(8080) + self.db = None + + @property + def cmd(self): + return "rethinkdb" + + @property + def cmd_local(self): + return CONFIG.rethink_executable + + def get_args(self, **kwargs): + cmd = [ + '--bind', self._listen_hostname, + '--driver-port', str(self.port), + '--http-port', str(self.http_port), + '--cluster-port', str(self.cluster_port), + ] + + if 'workspace' in kwargs: + cmd += ['--directory', str(kwargs['workspace'] / 'db')] + + return cmd + + @property + def image(self): + return CONFIG.rethink_image + + @property + def port(self): + return self._driver_port + + @property + def cluster_port(self): + return self._cluster_port + + @property + def http_port(self): + return self._http_port + + def check_server_up(self): + """Test connection to the server.""" + log.info("Connecting to RethinkDB at {0}:{1}".format( + self.hostname, self.port)) + + if not self.hostname: + return False + + try: + self.conn = r.connect(host=self.hostname, port=self.port, db='test') + return True + except rethinkdb.errors.RqlDriverError as err: + log.warning(err) + return False diff --git a/tests/functional/test_misc.py b/tests/functional/test_misc.py index 04ebbbd..ba5b86b 100644 --- a/tests/functional/test_misc.py +++ b/tests/functional/test_misc.py @@ -86,8 +86,8 @@ def test_filter_dict_match_bitwise(self, conn): Test bitwise operators and other bitwise operators """ expected = [ - {'id': 'bill-id', 'name': 'bill', 'age': 35}, - {'id': 'kimye-id', 'name': 'kimye', 'age': 17} + {'id': 'kimye-id', 'name': 'kimye', 'age': 17}, + {'id': 'bill-id', 'name': 'bill', 'age': 35} ] not_joe = r.row["id"] != "joe-id" @@ -97,7 +97,7 @@ def test_filter_dict_match_bitwise(self, conn): result = r.db('x').table('people').filter(not_joe & not_bob & (kimye | bill)).run(conn) # not joe and not bob and either kimye or bill - assertEqual(expected, list(result)) + assertEqual(sorted(expected, key=lambda i: i['age']), sorted(list(result), key=lambda i: i['age'])) class TestMapping(MockTest): diff --git a/tests/functional/test_order_by.py b/tests/functional/test_order_by.py index 26cbf35..160a6be 100644 --- a/tests/functional/test_order_by.py +++ b/tests/functional/test_order_by.py @@ -69,6 +69,8 @@ def test_sort_1_attr_2_desc(self, conn): assertEqual(expected, list(result)) def test_sort_1_attr_2_asc_index(self, conn): + r.db('y').table('scores').index_create('score').run(conn) + r.db('y').table('scores').index_wait().run(conn) expected = [ {'id': 'todd', 'age': 52, 'score': 15}, {'id': 'joe', 'age': 26, 'score': 60},