diff --git a/.github/workflows/test-dragonfly.yml b/.github/workflows/test-dragonfly.yml new file mode 100644 index 00000000..54ea075c --- /dev/null +++ b/.github/workflows/test-dragonfly.yml @@ -0,0 +1,79 @@ +--- +name: Test Dragonfly + +on: + workflow_dispatch: + + +concurrency: + group: dragon-fly-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + tests: + - "test_json" + - "test_mixins" + - "test_stack" + - "test_connection.py" + - "test_asyncredis.py" + - "test_general.py" + - "test_scan.py" + - "test_zadd.py" + - "test_translations.py" + - "test_sortedset_commands.py" + permissions: + pull-requests: write + services: + redis: + image: docker.dragonflydb.io/dragonflydb/dragonfly:latest + ports: + - 6380:6379 + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + cache-dependency-path: poetry.lock + python-version: 3.12 + - name: Install dependencies + env: + PYTHON_KEYRING_BACKEND: keyring.backends.null.Keyring + run: | + python -m pip --quiet install poetry + echo "$HOME/.poetry/bin" >> $GITHUB_PATH + poetry install + poetry run pip install "fakeredis[json,bf,cf,lua]" + + - name: Test without coverage + run: | + poetry run pytest test/${{ matrix.tests }} \ + --html=report-${{ matrix.tests }}.html \ + --self-contained-html \ + -v + - name: Upload Tests Result + if: always() + uses: actions/upload-artifact@v4 + with: + name: tests-result-${{ matrix.tests }} + path: report-${{ matrix.tests }}.html + + upload-results: + needs: test + if: always() + runs-on: ubuntu-latest + steps: + - name: Collect Tests Result + uses: actions/upload-artifact/merge@v4 + with: + delete-merged: true \ No newline at end of file diff --git a/docs/about/changelog.md b/docs/about/changelog.md index f01072f8..a383f929 100644 --- a/docs/about/changelog.md +++ b/docs/about/changelog.md @@ -9,6 +9,16 @@ description: Change log of all fakeredis releases - Support for TIME SERIES commands (no support for align arguments on some commands) #310 +### 🐛 Bug Fixes + +- fix:xrevrange to work with exclusive ranges @hurlenko #319 + +### 🧰 Maintenance + +- Update all dependencies, particularly pytest to v8 +- Add tests against Dragonfly server #318 +- Implement decocator `unsupported_server_types` to enable excluding tests from running against certain server types #318 + ## v2.23.5 ### 🐛 Bug Fixes diff --git a/docs/requirements.txt b/docs/requirements.txt index d3c487c1..0dc96d78 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,2 +1,2 @@ mkdocs==1.6.0 -mkdocs-material==9.5.31 +mkdocs-material==9.5.33 diff --git a/poetry.lock b/poetry.lock index 9ba995bd..582090bb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -25,9 +25,6 @@ files = [ {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, ] -[package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} - [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] @@ -483,24 +480,25 @@ dev = ["pyTest", "pyTest-cov"] [[package]] name = "hypothesis" -version = "6.79.4" +version = "6.111.1" description = "A library for property-based testing" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "hypothesis-6.79.4-py3-none-any.whl", hash = "sha256:5ce05bc70aa4f20114effaf3375dc8b51d09a04026a0cf89d4514fc0b69f6304"}, - {file = "hypothesis-6.79.4.tar.gz", hash = "sha256:e9a9ff3dc3f3eebbf214d6852882ac96ad72023f0e9770139fd3d3c1b87673e2"}, + {file = "hypothesis-6.111.1-py3-none-any.whl", hash = "sha256:9422adbac4b2104f6cf92dc6604b5c9df975efc08ffc7145ecc39bc617243835"}, + {file = "hypothesis-6.111.1.tar.gz", hash = "sha256:6ab6185a858fa692bf125c0d0a936134edc318bee01c05e407c71c9ead0b61c5"}, ] [package.dependencies] -attrs = ">=19.2.0" +attrs = ">=22.2.0" exceptiongroup = {version = ">=1.0.0", markers = "python_version < \"3.11\""} sortedcontainers = ">=2.1.0,<3.0.0" [package.extras] -all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "django (>=3.2)", "dpcontracts (>=0.4)", "importlib-metadata (>=3.6)", "lark (>=0.10.1)", "libcst (>=0.3.16)", "numpy (>=1.17.3)", "pandas (>=1.1)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2023.3)"] +all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "crosshair-tool (>=0.0.66)", "django (>=3.2)", "dpcontracts (>=0.4)", "hypothesis-crosshair (>=0.0.12)", "lark (>=0.10.1)", "libcst (>=0.3.16)", "numpy (>=1.17.3)", "pandas (>=1.1)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2024.1)"] cli = ["black (>=19.10b0)", "click (>=7.0)", "rich (>=9.0.0)"] codemods = ["libcst (>=0.3.16)"] +crosshair = ["crosshair-tool (>=0.0.66)", "hypothesis-crosshair (>=0.0.12)"] dateutil = ["python-dateutil (>=1.4)"] django = ["django (>=3.2)"] dpcontracts = ["dpcontracts (>=0.4)"] @@ -511,17 +509,17 @@ pandas = ["pandas (>=1.1)"] pytest = ["pytest (>=4.6)"] pytz = ["pytz (>=2014.1)"] redis = ["redis (>=3.0.0)"] -zoneinfo = ["backports.zoneinfo (>=0.2.1)", "tzdata (>=2023.3)"] +zoneinfo = ["backports.zoneinfo (>=0.2.1)", "tzdata (>=2024.1)"] [[package]] name = "idna" -version = "3.7" +version = "3.8" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"}, + {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, ] [[package]] @@ -555,6 +553,23 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] +[[package]] +name = "jinja2" +version = "3.1.4" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + [[package]] name = "jsonpath-ng" version = "1.6.1" @@ -664,6 +679,75 @@ files = [ {file = "lupa-2.2.tar.gz", hash = "sha256:665a006bcf8d9aacdfdb953824b929d06a0c55910a662b59be2f157ab4c8924d"}, ] +[[package]] +name = "markupsafe" +version = "2.1.5" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +] + [[package]] name = "mccabe" version = "0.7.0" @@ -735,13 +819,13 @@ files = [ [[package]] name = "packaging" -version = "24.0" +version = "24.1" description = "Core utilities for Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] [[package]] @@ -773,18 +857,15 @@ type = ["mypy (>=1.8)"] [[package]] name = "pluggy" -version = "1.2.0" +version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, - {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] -[package.dependencies] -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} - [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] @@ -912,55 +993,53 @@ files = [ [[package]] name = "pytest" -version = "7.4.4" +version = "8.3.2" description = "pytest: simple powerful testing with Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, - {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, + {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, + {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, ] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} +pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-asyncio" -version = "0.21.2" +version = "0.24.0" description = "Pytest support for asyncio" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pytest_asyncio-0.21.2-py3-none-any.whl", hash = "sha256:ab664c88bb7998f711d8039cacd4884da6430886ae8bbd4eded552ed2004f16b"}, - {file = "pytest_asyncio-0.21.2.tar.gz", hash = "sha256:d67738fc232b94b326b9d060750beb16e0074210b98dd8b58a5239fa2a154f45"}, + {file = "pytest_asyncio-0.24.0-py3-none-any.whl", hash = "sha256:a811296ed596b69bf0b6f3dc40f83bcaf341b155a269052d82efa2b25ac7037b"}, + {file = "pytest_asyncio-0.24.0.tar.gz", hash = "sha256:d081d828e576d85f875399194281e92bf8a68d60d72d1a2faf2feddb6c46b276"}, ] [package.dependencies] -pytest = ">=7.0.0" -typing-extensions = {version = ">=3.7.2", markers = "python_version < \"3.8\""} +pytest = ">=8.2,<9" [package.extras] docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] -testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"] +testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] [[package]] name = "pytest-cov" -version = "4.1.0" +version = "5.0.0" description = "Pytest plugin for measuring coverage." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, - {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, + {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, + {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, ] [package.dependencies] @@ -968,7 +1047,44 @@ coverage = {version = ">=5.2.1", extras = ["toml"]} pytest = ">=4.6" [package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] + +[[package]] +name = "pytest-html" +version = "4.1.1" +description = "pytest plugin for generating HTML reports" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest_html-4.1.1-py3-none-any.whl", hash = "sha256:c8152cea03bd4e9bee6d525573b67bbc6622967b72b9628dda0ea3e2a0b5dd71"}, + {file = "pytest_html-4.1.1.tar.gz", hash = "sha256:70a01e8ae5800f4a074b56a4cb1025c8f4f9b038bba5fe31e3c98eb996686f07"}, +] + +[package.dependencies] +jinja2 = ">=3.0.0" +pytest = ">=7.0.0" +pytest-metadata = ">=2.0.0" + +[package.extras] +docs = ["pip-tools (>=6.13.0)"] +test = ["assertpy (>=1.1)", "beautifulsoup4 (>=4.11.1)", "black (>=22.1.0)", "flake8 (>=4.0.1)", "pre-commit (>=2.17.0)", "pytest-mock (>=3.7.0)", "pytest-rerunfailures (>=11.1.2)", "pytest-xdist (>=2.4.0)", "selenium (>=4.3.0)", "tox (>=3.24.5)"] + +[[package]] +name = "pytest-metadata" +version = "3.1.1" +description = "pytest plugin for test session metadata" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest_metadata-3.1.1-py3-none-any.whl", hash = "sha256:c8e0844db684ee1c798cfa38908d20d67d0463ecb6137c72e91f418558dd5f4b"}, + {file = "pytest_metadata-3.1.1.tar.gz", hash = "sha256:d2a29b0355fbc03f168aa96d41ff88b1a3b44a3b02acbe491801c98a048017c8"}, +] + +[package.dependencies] +pytest = ">=7.0.0" + +[package.extras] +test = ["black (>=22.1.0)", "flake8 (>=4.0.1)", "pre-commit (>=2.17.0)", "tox (>=3.24.5)"] [[package]] name = "pytest-mock" @@ -1210,4 +1326,4 @@ probabilistic = ["pyprobables"] [metadata] lock-version = "2.0" python-versions = "^3.7" -content-hash = "b19f18b5e7b62da51c2039313824d4e82bc1c18b1765b6303fee4004a6356509" +content-hash = "f24404933405f1e7742e6a3d31003b21554541051c3f1d0960e3b84e0798b453" diff --git a/pyproject.toml b/pyproject.toml index b686f050..1a3ace61 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ packages = [ { include = "fakeredis" }, { include = "LICENSE" }, ] -version = "2.23.5" +version = "2.24.0" description = "Python implementation of redis API, can be used for testing purposes." readme = "README.md" keywords = ["redis", "RedisJson", "RedisBloom", "tests", "redis-stack"] @@ -66,15 +66,16 @@ coverage = "^7" black = { version = "^24.4.2", python = ">=3.8.1" } flake8 = { version = "^7", python = ">=3.8.1" } flake8-pyproject = { version = "^1", python = ">=3.8.1" } -hypothesis = "^6.70" mypy = { version = "^1.10", python = ">=3.8.1" } [tool.poetry.group.test.dependencies] -pytest = "^7.4" +pytest = { version = "^8.3", python = ">=3.8.1" } +hypothesis = { version = "^6.111", python = ">=3.8.1" } pytest-timeout = "^2.3.1" -pytest-asyncio = "^0.21" -pytest-cov = "^4.1" +pytest-asyncio = { version = "^0.24", python = ">=3.8.1" } +pytest-cov = { version = "^5.0", python = ">=3.8.1" } pytest-mock = { version = "^3.14", python = ">=3.8.1" } +pytest-html = { version = "^4.1", python = ">=3.8.1" } [tool.poetry.group.docs.dependencies] python-dotenv = { version = "^1", python = ">=3.8.1" } @@ -86,6 +87,7 @@ pygithub = "^2.3" "Documentation" = "https://fakeredis.moransoftware.ca/" [tool.pytest.ini_options] +asyncio_default_fixture_loop_scope = "function" markers = [ "slow: marks tests as slow (deselect with '-m \"not slow\"')", "fake: run tests only with fake redis", @@ -94,8 +96,10 @@ markers = [ "min_server", "max_server", "decode_responses", + "unsupported_server_types", ] asyncio_mode = "strict" +generate_report_on_test = true [tool.mypy] packages = ['fakeredis', ] diff --git a/test/conftest.py b/test/conftest.py index 8e2b2cb0..b05718ea 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -1,4 +1,4 @@ -from typing import Callable, Union +from typing import Callable, Tuple, Union, Optional import pytest import pytest_asyncio @@ -18,22 +18,26 @@ def _check_lua_module_supported() -> bool: @pytest_asyncio.fixture(scope="session") -def real_redis_version() -> Union[None, str]: +def real_redis_version() -> Tuple[str, Union[None, Tuple[int, ...]]]: """Returns server's version or None if server is not running""" client = None try: client = redis.StrictRedis("localhost", port=6380, db=2) - server_version = client.info()["redis_version"] - return server_version + client_info = client.info() + server_type = "dragonfly" if "dragonfly_version" in client_info else "redis" + server_version = client_info["redis_version"] if server_type != "dragonfly" else (7, 0) + server_version = _create_version(server_version) or (7,) + return server_type, server_version except redis.ConnectionError: - return None + pytest.exit("Redis is not running") + return "redis", (6,) finally: if hasattr(client, "close"): client.close() # Absent in older versions of redis-py @pytest_asyncio.fixture(name="fake_server") -def _fake_server(request): +def _fake_server(request) -> fakeredis.FakeServer: min_server_marker = request.node.get_closest_marker("min_server") server_version = min_server_marker.args[0] if min_server_marker else "6.2" server = fakeredis.FakeServer(version=server_version) @@ -70,10 +74,12 @@ def _marker_version_value(request, marker_name: str): ) def _create_redis(request) -> Callable[[int], redis.Redis]: cls_name = request.param - server_version = request.getfixturevalue("real_redis_version") + server_type, server_version = request.getfixturevalue("real_redis_version") if not cls_name.startswith("Fake") and not server_version: pytest.skip("Redis is not running") - server_version = _create_version(server_version) or (6,) + unsupported_server_types = request.node.get_closest_marker("unsupported_server_types") + if unsupported_server_types and server_type in unsupported_server_types.args: + pytest.skip(f"Server type {server_type} is not supported") min_server = _marker_version_value(request, "min_server") max_server = _marker_version_value(request, "max_server") if server_version < min_server: @@ -103,10 +109,12 @@ def factory(db=2): params=[pytest.param("fake", marks=pytest.mark.fake), pytest.param("real", marks=pytest.mark.real)], ) async def _req_aioredis2(request) -> redis.asyncio.Redis: - server_version = request.getfixturevalue("real_redis_version") + server_type, server_version = request.getfixturevalue("real_redis_version") if request.param != "fake" and not server_version: pytest.skip("Redis is not running") - server_version = _create_version(server_version) or (6,) + unsupported_server_types = request.node.get_closest_marker("unsupported_server_types") + if unsupported_server_types and server_type in unsupported_server_types.args: + pytest.skip(f"Server type {server_type} is not supported") min_server_marker = _marker_version_value(request, "min_server") max_server_marker = _marker_version_value(request, "max_server") if server_version < min_server_marker: @@ -117,6 +125,7 @@ async def _req_aioredis2(request) -> redis.asyncio.Redis: lua_modules = set(lua_modules_marker.args) if lua_modules_marker else None if lua_modules and not _check_lua_module_supported(): pytest.skip("LUA modules not supported by fakeredis") + fake_server: Optional[fakeredis.FakeServer] if request.param == "fake": fake_server = request.getfixturevalue("fake_server") ret = fakeredis.FakeAsyncRedis(server=fake_server, lua_modules=lua_modules) diff --git a/test/test_json/test_json.py b/test/test_json/test_json.py index c745db8a..ebdc13c4 100644 --- a/test/test_json/test_json.py +++ b/test/test_json/test_json.py @@ -435,14 +435,7 @@ def test_decode_response_disabaled_null(r: redis.Redis): def test_json_get_jset(r: redis.Redis): - assert ( - r.json().set( - "foo", - Path.root_path(), - "bar", - ) - == 1 - ) + assert r.json().set("foo", Path.root_path(), "bar") == 1 assert "bar" == r.json().get("foo") assert r.json().get("baz") is None assert 1 == r.json().delete("foo") @@ -509,19 +502,9 @@ def test_set_path(r: redis.Redis): def test_type(r: redis.Redis): - r.json().set( - "1", - Path.root_path(), - 1, - ) + r.json().set("1", Path.root_path(), 1) - assert ( - r.json().type( - "1", - Path.root_path(), - ) - == b"integer" - ) + assert r.json().type("1", Path.root_path()) == b"integer" assert r.json().type("1") == b"integer" # noqa: E721 meta_data = { @@ -553,15 +536,8 @@ def test_objlen(r: redis.Redis): obj = {"foo": "bar", "baz": "qaz"} - r.json().set( - "obj", - Path.root_path(), - obj, - ) - assert len(obj) == r.json().objlen( - "obj", - Path.root_path(), - ) + r.json().set("obj", Path.root_path(), obj) + assert len(obj) == r.json().objlen("obj", Path.root_path()) r.json().set("obj", Path.root_path(), obj) assert len(obj) == r.json().objlen("obj") diff --git a/test/test_json/test_json_arr_commands.py b/test/test_json/test_json_arr_commands.py index c1662cde..0638ad03 100644 --- a/test/test_json/test_json_arr_commands.py +++ b/test/test_json/test_json_arr_commands.py @@ -382,32 +382,12 @@ def test_arrinsert(r: redis.Redis): [0, 4], ) - assert ( - r.json().arrinsert( - "arr", - Path.root_path(), - 1, - *[1, 2, 3], - ) - == 5 - ) + assert r.json().arrinsert("arr", Path.root_path(), 1, *[1, 2, 3]) == 5 assert r.json().get("arr") == [0, 1, 2, 3, 4] # test prepends - r.json().set( - "val2", - Path.root_path(), - [5, 6, 7, 8, 9], - ) - assert ( - r.json().arrinsert( - "val2", - Path.root_path(), - 0, - ["some", "thing"], - ) - == 6 - ) + r.json().set("val2", Path.root_path(), [5, 6, 7, 8, 9]) + assert r.json().arrinsert("val2", Path.root_path(), 0, ["some", "thing"]) == 6 assert r.json().get("val2") == [["some", "thing"], 5, 6, 7, 8, 9] r.json().set( "doc1", @@ -456,37 +436,10 @@ def test_arrpop(r: redis.Redis): Path.root_path(), [0, 1, 2, 3, 4], ) - assert ( - r.json().arrpop( - "arr", - Path.root_path(), - 4, - ) - == 4 - ) - assert ( - r.json().arrpop( - "arr", - Path.root_path(), - -1, - ) - == 3 - ) - assert ( - r.json().arrpop( - "arr", - Path.root_path(), - ) - == 2 - ) - assert ( - r.json().arrpop( - "arr", - Path.root_path(), - 0, - ) - == 0 - ) + assert r.json().arrpop("arr", Path.root_path(), 4) == 4 + assert r.json().arrpop("arr", Path.root_path(), -1) == 3 + assert r.json().arrpop("arr", Path.root_path()) == 2 + assert r.json().arrpop("arr", Path.root_path(), 0) == 0 assert r.json().get("arr") == [1] # test out of bounds @@ -495,14 +448,7 @@ def test_arrpop(r: redis.Redis): Path.root_path(), [0, 1, 2, 3, 4], ) - assert ( - r.json().arrpop( - "arr", - Path.root_path(), - 99, - ) - == 4 - ) + assert r.json().arrpop("arr", Path.root_path(), 99) == 4 # none test r.json().set( @@ -548,15 +494,7 @@ def test_arrtrim(r: redis.Redis): [0, 1, 2, 3, 4], ) - assert ( - r.json().arrtrim( - "arr", - Path.root_path(), - 1, - 3, - ) - == 3 - ) + assert r.json().arrtrim("arr", Path.root_path(), 1, 3) == 3 assert r.json().get("arr") == [1, 2, 3] # <0 test, should be 0 equivalent @@ -565,15 +503,7 @@ def test_arrtrim(r: redis.Redis): Path.root_path(), [0, 1, 2, 3, 4], ) - assert ( - r.json().arrtrim( - "arr", - Path.root_path(), - -1, - 3, - ) - == 0 - ) + assert r.json().arrtrim("arr", Path.root_path(), -1, 3) == 0 # testing stop > end r.json().set( @@ -581,15 +511,7 @@ def test_arrtrim(r: redis.Redis): Path.root_path(), [0, 1, 2, 3, 4], ) - assert ( - r.json().arrtrim( - "arr", - Path.root_path(), - 3, - 99, - ) - == 2 - ) + assert r.json().arrtrim("arr", Path.root_path(), 3, 99) == 2 # start > array size and stop r.json().set( @@ -597,15 +519,7 @@ def test_arrtrim(r: redis.Redis): Path.root_path(), [0, 1, 2, 3, 4], ) - assert ( - r.json().arrtrim( - "arr", - Path.root_path(), - 9, - 1, - ) - == 0 - ) + assert r.json().arrtrim("arr", Path.root_path(), 9, 1) == 0 # all larger r.json().set( @@ -613,15 +527,7 @@ def test_arrtrim(r: redis.Redis): Path.root_path(), [0, 1, 2, 3, 4], ) - assert ( - r.json().arrtrim( - "arr", - Path.root_path(), - 9, - 11, - ) - == 0 - ) + assert r.json().arrtrim("arr", Path.root_path(), 9, 11) == 0 r.json().set( "doc1", diff --git a/test/test_mixins/test_geo_commands.py b/test/test_mixins/test_geo_commands.py index 66192407..bf00809a 100644 --- a/test/test_mixins/test_geo_commands.py +++ b/test/test_mixins/test_geo_commands.py @@ -149,6 +149,7 @@ def test_geodist_missing_one_member(r: redis.Redis): assert r.geodist("barcelona", "place1", "missing_member", "km") is None +@pytest.mark.unsupported_server_types("dragonfly") @pytest.mark.parametrize( "long,lat,radius,extra,expected", [ @@ -172,6 +173,7 @@ def test_georadius(r: redis.Redis, long: float, lat: float, radius: float, extra assert r.georadius("barcelona", long, lat, radius, **extra) == expected +@pytest.mark.unsupported_server_types("dragonfly") @pytest.mark.parametrize( "member,radius,extra,expected", [ @@ -196,6 +198,7 @@ def test_georadiusbymember(r: redis.Redis, member: str, radius: float, extra: Di assert r.zcard("extract") == len(expected) +@pytest.mark.unsupported_server_types("dragonfly") def test_georadius_with(r: redis.Redis): values = ( 2.1909389952632, @@ -240,6 +243,7 @@ def test_georadius_with(r: redis.Redis): ) +@pytest.mark.unsupported_server_types("dragonfly") def test_georadius_count(r: redis.Redis): values = ( 2.1909389952632, diff --git a/test/test_mixins/test_list_commands.py b/test/test_mixins/test_list_commands.py index f42b40ef..e04d7a78 100644 --- a/test/test_mixins/test_list_commands.py +++ b/test/test_mixins/test_list_commands.py @@ -521,6 +521,7 @@ def test_brpoplpush_multi_keys(r: redis.Redis): assert r.lrem("bar", -1, "two") == 1 +@pytest.mark.unsupported_server_types("dragonfly") # TODO Should this be supported? def test_brpoplpush_wrong_type(r: redis.Redis): r.set("foo", "bar") r.rpush("list", "element") @@ -654,6 +655,7 @@ def test_lpos(r: redis.Redis): assert r.lpos("a", "c", count=0, maxlen=7, rank=2) == [6] +@pytest.mark.unsupported_server_types("dragonfly") @pytest.mark.min_server("7") def test_blmpop(r: redis.Redis): r.rpush("a", "1", "2", "3", "4", "5") @@ -666,6 +668,7 @@ def test_blmpop(r: redis.Redis): assert r.blmpop(1, "2", "foo", "bar", direction="RIGHT") is None +@pytest.mark.unsupported_server_types("dragonfly") @pytest.mark.min_server("7") def test_lmpop(r: redis.Redis): r.rpush("foo", "1", "2", "3", "4", "5") diff --git a/test/test_mixins/test_server_commands.py b/test/test_mixins/test_server_commands.py index b9be46b4..367684e9 100644 --- a/test/test_mixins/test_server_commands.py +++ b/test/test_mixins/test_server_commands.py @@ -9,6 +9,7 @@ from test.testtools import fake_only +@pytest.mark.unsupported_server_types("dragonfly") def test_swapdb(r, create_redis): r1 = create_redis(3) r.set("foo", "abc") @@ -24,6 +25,7 @@ def test_swapdb(r, create_redis): assert r1.get("baz") is None +@pytest.mark.unsupported_server_types("dragonfly") def test_swapdb_same_db(r: redis.Redis): assert r.swapdb(1, 1) @@ -32,6 +34,7 @@ def test_save(r: redis.Redis): assert r.save() +@pytest.mark.unsupported_server_types("dragonfly") def test_bgsave(r: redis.Redis): assert r.bgsave() with pytest.raises(ResponseError): @@ -56,6 +59,7 @@ def test_command_count(r: redis.Redis): assert r.command_count() >= len([cmd for cmd in SUPPORTED_COMMANDS if " " not in cmd]) +@pytest.mark.unsupported_server_types("dragonfly") @pytest.mark.slow def test_bgsave_timestamp_update(r: redis.Redis): early_timestamp = r.lastsave() diff --git a/test/test_mixins/test_sortedset_commands.py b/test/test_sortedset_commands.py similarity index 99% rename from test/test_mixins/test_sortedset_commands.py rename to test/test_sortedset_commands.py index 066274ce..4c3d3d75 100644 --- a/test/test_mixins/test_sortedset_commands.py +++ b/test/test_sortedset_commands.py @@ -867,6 +867,7 @@ def test_zunionstore_nan_to_zero_ordering(r: redis.Redis): assert r.zscore("baz", "e1") == 0.0 +@pytest.mark.unsupported_server_types("dragonfly") # TODO Should pass? def test_zunionstore_mixed_set_types(r: redis.Redis): # No score, redis will use 1.0. r.sadd("foo", "one") @@ -887,6 +888,7 @@ def test_zunionstore_badkey(r: redis.Redis): assert r.zrange("baz", 0, -1, withscores=True) == [(b"one", 1), (b"two", 2)] +@pytest.mark.unsupported_server_types("dragonfly") # TODO Should pass? def test_zunionstore_wrong_type(r: redis.Redis): r.set("foo", "bar") with pytest.raises(redis.ResponseError): @@ -903,6 +905,7 @@ def test_zinterstore(r: redis.Redis): assert r.zrange("baz", 0, -1, withscores=True) == [(b"one", 2), (b"two", 4)] +@pytest.mark.unsupported_server_types("dragonfly") def test_zinterstore_mixed_set_types(r: redis.Redis): r.sadd("foo", "one") r.sadd("foo", "two") @@ -934,6 +937,7 @@ def test_zinterstore_nokey(r: redis.Redis): r.zinterstore("baz", [], aggregate="MAX") +@pytest.mark.unsupported_server_types("dragonfly") # TODO causes a crash! def test_zinterstore_nan_to_zero(r: redis.Redis): r.zadd("foo", {"x": math.inf}) r.zadd("foo2", {"x": math.inf}) @@ -946,6 +950,7 @@ def test_zunionstore_nokey(r: redis.Redis): r.zunionstore("baz", [], aggregate="MAX") +@pytest.mark.unsupported_server_types("dragonfly") # TODO Hang server def test_zinterstore_wrong_type(r: redis.Redis): r.set("foo", "bar") with pytest.raises(redis.ResponseError): diff --git a/test/test_stack/test_bloom_redis_py.py b/test/test_stack/test_bloom_redis_py.py index adabc11f..91093dfb 100644 --- a/test/test_stack/test_bloom_redis_py.py +++ b/test/test_stack/test_bloom_redis_py.py @@ -9,11 +9,15 @@ def intlist(obj): return [int(v) for v in obj] -def test_create(r: redis.Redis): +def test_create_bf(r: redis.Redis): """Test CREATE/RESERVE calls""" assert r.bf().create("bloom", 0.01, 1000) assert r.bf().create("bloom_e", 0.01, 1000, expansion=1) assert r.bf().create("bloom_ns", 0.01, 1000, noScale=True) + + +@pytest.mark.unsupported_server_types("dragonfly") +def test_create_cf(r: redis.Redis): assert r.cf().create("cuckoo", 1000) assert r.cf().create("cuckoo_e", 1000, expansion=1) assert r.cf().create("cuckoo_bs", 1000, bucket_size=4) @@ -42,6 +46,7 @@ def test_bf_add(r: redis.Redis): assert [1, 0] == intlist(r.bf().mexists("bloom", "foo", "noexist")) +@pytest.mark.unsupported_server_types("dragonfly") def test_bf_insert(r: redis.Redis): assert r.bf().create("bloom", 0.01, 1000) assert [1] == intlist(r.bf().insert("bloom", ["foo"])) @@ -57,6 +62,7 @@ def test_bf_insert(r: redis.Redis): assert 1 == info.get("filterNum") +@pytest.mark.unsupported_server_types("dragonfly") def test_bf_scandump_and_loadchunk(r: redis.Redis): r.bf().create("myBloom", "0.0001", "1000") @@ -92,6 +98,7 @@ def test_bf_scandump_and_loadchunk(r: redis.Redis): assert r.bf().exists("myBloom1", x), f"{x} not in filter" +@pytest.mark.unsupported_server_types("dragonfly") def test_bf_info(r: redis.Redis): # Store a filter r.bf().create("nonscaling", "0.0001", "1000", noScale=True) @@ -106,6 +113,7 @@ def test_bf_info(r: redis.Redis): assert info.insertedNum == 0 +@pytest.mark.unsupported_server_types("dragonfly") def test_bf_card(r: redis.Redis): # return 0 if the key does not exist assert r.bf().card("not_exist") == 0 diff --git a/test/test_stack/test_bloomfilter.py b/test/test_stack/test_bloomfilter.py index de968c51..dfbef61b 100644 --- a/test/test_stack/test_bloomfilter.py +++ b/test/test_stack/test_bloomfilter.py @@ -24,6 +24,7 @@ def test_bf_madd(r: redis.Redis): r.bf().add("key1", "v") +@pytest.mark.unsupported_server_types("dragonfly") def test_bf_card(r: redis.Redis): assert r.bf().madd("key", "v1", "v2", "v3") == [1, 1, 1] assert r.bf().card("key") == 3 @@ -69,6 +70,7 @@ def test_bf_reserve(r: redis.Redis): assert r.bf().reserve("bloom", 0.01, 1000) +@pytest.mark.unsupported_server_types("dragonfly") def test_bf_insert(r: redis.Redis): assert r.bf().create("bloom", 0.01, 1000) assert r.bf().insert("bloom", ["foo"]) == [1] diff --git a/test/test_stack/test_cms.py b/test/test_stack/test_cms.py index cadd513f..fae4ea54 100644 --- a/test/test_stack/test_cms.py +++ b/test/test_stack/test_cms.py @@ -6,6 +6,7 @@ json_tests = pytest.importorskip("probables") +@pytest.mark.unsupported_server_types("dragonfly") def test_cms_create(r: redis.Redis): assert r.cms().initbydim("cmsDim", 100, 5) assert r.cms().initbyprob("cmsProb", 0.01, 0.01) @@ -29,6 +30,7 @@ def test_cms_create(r: redis.Redis): r.cms().initbyprob("cmsProb2", 0.01, 0) +@pytest.mark.unsupported_server_types("dragonfly") def test_cms_incrby(r: redis.Redis): assert r.cms().initbydim("cmsDim", 100, 5) assert r.cms().initbyprob("cmsProb", 0.01, 0.01) @@ -55,6 +57,7 @@ def test_cms_incrby(r: redis.Redis): r.cms().incrby("cmsDim", ["foo", "bar"], [3, "four"]) +@pytest.mark.unsupported_server_types("dragonfly") def test_cms_merge(r: redis.Redis): assert r.cms().initbydim("cmsDim", 100, 5) assert r.cms().initbydim("cms2", 100, 5) @@ -80,6 +83,7 @@ def test_cms_merge(r: redis.Redis): r.cms().merge("cmsDim", 2, ["cms2", "noexist"], [4, 3]) +@pytest.mark.unsupported_server_types("dragonfly") def test_cms_info(r: redis.Redis): assert r.cms().initbydim("A", 1000, 5) assert r.cms().initbydim("B", 1000, 5) @@ -107,6 +111,7 @@ def test_cms_info(r: redis.Redis): @pytest.mark.xfail(reason="Bug in pyprobables") +@pytest.mark.unsupported_server_types("dragonfly") def test_cms_merge_fail(r: redis.Redis): assert r.cms().initbydim("A", 1000, 5) assert r.cms().initbydim("B", 1000, 5) diff --git a/test/test_stack/test_cuckoofilter.py b/test/test_stack/test_cuckoofilter.py index ba4142f8..60da26c8 100644 --- a/test/test_stack/test_cuckoofilter.py +++ b/test/test_stack/test_cuckoofilter.py @@ -4,6 +4,7 @@ cuckoofilters_tests = pytest.importorskip("probables") +@pytest.mark.unsupported_server_types("dragonfly") def test_cf_add_and_insert(r: redis.Redis): assert r.cf().create("cuckoo", 1000) assert r.cf().add("cuckoo", "filter") @@ -23,6 +24,7 @@ def test_cf_add_and_insert(r: redis.Redis): assert info.get("filterNum") == 1 +@pytest.mark.unsupported_server_types("dragonfly") def test_cf_exists_and_del(r: redis.Redis): assert r.cf().create("cuckoo", 1000) assert r.cf().add("cuckoo", "filter") diff --git a/test/test_stack/test_tdigest.py b/test/test_stack/test_tdigest.py index 3b808ca0..74ae7305 100644 --- a/test/test_stack/test_tdigest.py +++ b/test/test_stack/test_tdigest.py @@ -6,7 +6,7 @@ topk_tests = pytest.importorskip("probables") -@pytest.mark.experimental +@pytest.mark.unsupported_server_types("dragonfly") def test_tdigest_reset(r: redis.Redis): assert r.tdigest().create("tDigest", 10) # reset on empty histogram @@ -20,7 +20,7 @@ def test_tdigest_reset(r: redis.Redis): assert 0 == info.get("unmerged_weight") -@pytest.mark.onlynoncluster +@pytest.mark.unsupported_server_types("dragonfly") def test_tdigest_merge(r: redis.Redis): assert r.tdigest().create("to-tDigest", 10) assert r.tdigest().create("from-tDigest", 10) @@ -42,7 +42,7 @@ def test_tdigest_merge(r: redis.Redis): assert 4.0 == r.tdigest().max("to-tDigest") -@pytest.mark.experimental +@pytest.mark.unsupported_server_types("dragonfly") def test_tdigest_min_and_max(r: redis.Redis): assert r.tdigest().create("tDigest", 100) # insert data-points into sketch @@ -52,7 +52,7 @@ def test_tdigest_min_and_max(r: redis.Redis): assert 1 == r.tdigest().min("tDigest") -@pytest.mark.experimental +@pytest.mark.unsupported_server_types("dragonfly") def test_tdigest_quantile(r: redis.Redis): assert r.tdigest().create("tDigest", 500) # insert data-points into sketch @@ -72,7 +72,7 @@ def test_tdigest_quantile(r: redis.Redis): assert [3.0, 5.0] == r.tdigest().quantile("t-digest", 0.5, 0.8) -@pytest.mark.experimental +@pytest.mark.unsupported_server_types("dragonfly") def test_tdigest_cdf(r: redis.Redis): assert r.tdigest().create("tDigest", 100) # insert data-points into sketch @@ -83,7 +83,7 @@ def test_tdigest_cdf(r: redis.Redis): assert [0.1, 0.9] == [round(x, 1) for x in res] -@pytest.mark.experimental +@pytest.mark.unsupported_server_types("dragonfly") def test_tdigest_trimmed_mean(r: redis.Redis): assert r.tdigest().create("tDigest", 100) # insert data-points into sketch @@ -92,7 +92,7 @@ def test_tdigest_trimmed_mean(r: redis.Redis): assert 4.5 == r.tdigest().trimmed_mean("tDigest", 0.4, 0.5) -@pytest.mark.experimental +@pytest.mark.unsupported_server_types("dragonfly") def test_tdigest_rank(r: redis.Redis): assert r.tdigest().create("t-digest", 500) assert r.tdigest().add("t-digest", list(range(0, 20))) @@ -102,7 +102,7 @@ def test_tdigest_rank(r: redis.Redis): assert [-1, 20, 9] == r.tdigest().rank("t-digest", -20, 20, 9) -@pytest.mark.experimental +@pytest.mark.unsupported_server_types("dragonfly") def test_tdigest_revrank(r: redis.Redis): assert r.tdigest().create("t-digest", 500) assert r.tdigest().add("t-digest", list(range(0, 20))) @@ -111,7 +111,7 @@ def test_tdigest_revrank(r: redis.Redis): assert [-1, 19, 9] == r.tdigest().revrank("t-digest", 21, 0, 10) -@pytest.mark.experimental +@pytest.mark.unsupported_server_types("dragonfly") def test_tdigest_byrank(r: redis.Redis): assert r.tdigest().create("t-digest", 500) assert r.tdigest().add("t-digest", list(range(1, 11))) @@ -122,7 +122,7 @@ def test_tdigest_byrank(r: redis.Redis): r.tdigest().byrank("t-digest", -1)[0] -@pytest.mark.experimental +@pytest.mark.unsupported_server_types("dragonfly") def test_tdigest_byrevrank(r: redis.Redis): assert r.tdigest().create("t-digest", 500) assert r.tdigest().add("t-digest", list(range(1, 11))) diff --git a/test/test_stack/test_timeseries.py b/test/test_stack/test_timeseries.py index 4cde2c1a..e76ddea2 100644 --- a/test/test_stack/test_timeseries.py +++ b/test/test_stack/test_timeseries.py @@ -10,6 +10,7 @@ timeseries_tests = pytest.importorskip("probables") +@pytest.mark.unsupported_server_types("dragonfly") def test_add_ts_close(r: redis.Redis): ts1 = r.ts().add(5, "*", 1) time.sleep(0.001) @@ -17,6 +18,7 @@ def test_add_ts_close(r: redis.Redis): assert abs(ts2 - ts1) < 5 +@pytest.mark.unsupported_server_types("dragonfly") def test_create_key_exist(r: redis.Redis): assert r.ts().create(1) with pytest.raises(redis.ResponseError) as e: @@ -24,12 +26,14 @@ def test_create_key_exist(r: redis.Redis): assert str(e.value) == msgs.TIMESERIES_KEY_EXISTS +@pytest.mark.unsupported_server_types("dragonfly") def test_create_bad_duplicate_policy(r: redis.Redis): with pytest.raises(redis.ResponseError) as e: assert r.ts().create(1, duplicate_policy="bad") assert str(e.value) == msgs.TIMESERIES_INVALID_DUPLICATE_POLICY +@pytest.mark.unsupported_server_types("dragonfly") def test_create(r: redis.Redis): assert r.ts().create(1) assert r.ts().create(2, retention_msecs=5) @@ -45,6 +49,7 @@ def test_create(r: redis.Redis): assert 128 == info.get("chunk_size") +@pytest.mark.unsupported_server_types("dragonfly") def test_create_duplicate_policy(r: redis.Redis): # Test for duplicate policy for duplicate_policy in ["block", "last", "first", "min", "max"]: @@ -54,6 +59,7 @@ def test_create_duplicate_policy(r: redis.Redis): assert duplicate_policy == info.get("duplicate_policy") +@pytest.mark.unsupported_server_types("dragonfly") def test_alter(r: redis.Redis): assert r.ts().create(1) info = r.ts().info(1) @@ -74,6 +80,7 @@ def test_alter(r: redis.Redis): assert str(e.value) == "TSDB: CHUNK_SIZE value must be a multiple of 8 in the range [48 .. 1048576]" +@pytest.mark.unsupported_server_types("dragonfly") def test_alter_diplicate_policy(r: redis.Redis): assert r.ts().create(1) info = r.ts().info(1) @@ -84,6 +91,7 @@ def test_alter_diplicate_policy(r: redis.Redis): assert "min" == info.get("duplicate_policy") +@pytest.mark.unsupported_server_types("dragonfly") def test_add(r: redis.Redis): assert 1 == r.ts().add(1, 1, 1) assert 2 == r.ts().add(2, 2, 3, retention_msecs=10) @@ -100,6 +108,7 @@ def test_add(r: redis.Redis): assert 128 == info.get("chunk_size") +@pytest.mark.unsupported_server_types("dragonfly") def test_add_before_retention(r: redis.Redis): r.ts().create("time-serie-1", retention_msecs=1000) assert r.ts().add("time-serie-1", 10000, 10.0) @@ -108,6 +117,7 @@ def test_add_before_retention(r: redis.Redis): assert str(e.value) == msgs.TIMESERIES_TIMESTAMP_OLDER_THAN_RETENTION +@pytest.mark.unsupported_server_types("dragonfly") def test_add_before_last(r: redis.Redis): r.ts().create("time-serie-1", retention_msecs=1000) assert r.ts().add("time-serie-1", 100, 10.0) == 100 @@ -122,6 +132,7 @@ def test_add_before_last(r: redis.Redis): ) +@pytest.mark.unsupported_server_types("dragonfly") def test_add_duplicate_policy(r: redis.Redis): # Test for duplicate policy BLOCK assert 1 == r.ts().add("time-serie-add-ooo-block", 1, 5.0) @@ -150,11 +161,13 @@ def test_add_duplicate_policy(r: redis.Redis): assert 5.0 == r.ts().get("time-serie-add-ooo-min")[1] +@pytest.mark.unsupported_server_types("dragonfly") def test_madd(r: redis.Redis): r.ts().create("a") assert [1, 2, 3] == r.ts().madd([("a", 1, 5), ("a", 2, 10), ("a", 3, 15)]) +@pytest.mark.unsupported_server_types("dragonfly") def test_incrby_decrby(r: redis.Redis): for _ in range(100): assert r.ts().incrby(1, 1) @@ -184,6 +197,7 @@ def test_incrby_decrby(r: redis.Redis): assert 128 == info.get("chunk_size") +@pytest.mark.unsupported_server_types("dragonfly") def test_create_and_delete_rule(r: redis.Redis): # test rule creation time = 100 @@ -208,6 +222,7 @@ def test_create_and_delete_rule(r: redis.Redis): assert info2["source_key"] is None +@pytest.mark.unsupported_server_types("dragonfly") def test_del_range(r: redis.Redis): with pytest.raises(redis.ResponseError) as e: r.ts().delete("test", 0, 100) @@ -222,6 +237,7 @@ def test_del_range(r: redis.Redis): assert r.ts().delete(1, 60, 3) == 0 +@pytest.mark.unsupported_server_types("dragonfly") def test_range(r: redis.Redis): for i in range(100): r.ts().add(1, i, i % 7) @@ -238,6 +254,7 @@ def test_range(r: redis.Redis): # assert 20 == len(r.ts().range(1, 0, 500, aggregation_type="avg", bucket_size_msec=10)) TODO +@pytest.mark.unsupported_server_types("dragonfly") def test_range_advanced(r: redis.Redis): for i in range(100): r.ts().add(1, i, i % 7) @@ -260,6 +277,7 @@ def test_range_advanced(r: redis.Redis): assert res == [(0, pytest.approx(2.55, 0.1)), (10, 3.0)] +@pytest.mark.unsupported_server_types("dragonfly") def test_range_latest(r: redis.Redis): timeseries = r.ts() timeseries.create("t1") @@ -277,6 +295,7 @@ def test_range_latest(r: redis.Redis): assert timeseries.range("t2", 0, 9) == [(0, 4.0)] +@pytest.mark.unsupported_server_types("dragonfly") def test_range_bucket_timestamp(r: redis.Redis): timeseries = r.ts() timeseries.create("t1") @@ -301,6 +320,7 @@ def test_range_bucket_timestamp(r: redis.Redis): ) == [(20, 4.0), (60, 3.0), (80, 5.0)] +@pytest.mark.unsupported_server_types("dragonfly") def test_range_empty(r: redis.Redis): timeseries = r.ts() timeseries.create("t1") @@ -331,6 +351,7 @@ def test_range_empty(r: redis.Redis): assert res == resp2_expected +@pytest.mark.unsupported_server_types("dragonfly") def test_rev_range(r: redis.Redis): for i in range(100): r.ts().add(1, i, i % 7) @@ -359,6 +380,7 @@ def test_rev_range(r: redis.Redis): @pytest.mark.onlynoncluster +@pytest.mark.unsupported_server_types("dragonfly") def test_revrange_latest(r: redis.Redis): timeseries = r.ts() timeseries.create("t1") @@ -374,6 +396,7 @@ def test_revrange_latest(r: redis.Redis): assert timeseries.revrange("t2", 0, 9, latest=True) == [(0, 4.0)] +@pytest.mark.unsupported_server_types("dragonfly") def test_revrange_bucket_timestamp(r: redis.Redis): timeseries = r.ts() timeseries.create("t1") @@ -398,6 +421,7 @@ def test_revrange_bucket_timestamp(r: redis.Redis): ) == [(20, 4.0), (60, 3.0), (80, 5.0)] +@pytest.mark.unsupported_server_types("dragonfly") def test_revrange_empty(r: redis.Redis): timeseries = r.ts() timeseries.create("t1") @@ -427,6 +451,7 @@ def test_revrange_empty(r: redis.Redis): @pytest.mark.onlynoncluster +@pytest.mark.unsupported_server_types("dragonfly") def test_mrange(r: redis.Redis): r.ts().create(1, labels={"Test": "This", "team": "ny"}) r.ts().create(2, labels={"Test": "This", "Taste": "That", "team": "sf"}) @@ -454,6 +479,7 @@ def test_mrange(r: redis.Redis): assert {"Test": "This", "team": "ny"} == res[0]["1"][0] +@pytest.mark.unsupported_server_types("dragonfly") def test_multi_range_advanced(r: redis.Redis): r.ts().create(1, labels={"Test": "This", "team": "ny"}) r.ts().create(2, labels={"Test": "This", "Taste": "That", "team": "sf"}) @@ -510,6 +536,7 @@ def test_multi_range_advanced(r: redis.Redis): @pytest.mark.onlynoncluster +@pytest.mark.unsupported_server_types("dragonfly") def test_mrange_latest(r: redis.Redis): timeseries = r.ts() timeseries.create("t1") @@ -534,6 +561,7 @@ def test_mrange_latest(r: redis.Redis): @pytest.mark.onlynoncluster +@pytest.mark.unsupported_server_types("dragonfly") def test_multi_reverse_range(r: redis.Redis): r.ts().create(1, labels={"Test": "This", "team": "ny"}) r.ts().create(2, labels={"Test": "This", "Taste": "That", "team": "sf"}) @@ -608,6 +636,7 @@ def test_multi_reverse_range(r: redis.Redis): @pytest.mark.onlynoncluster +@pytest.mark.unsupported_server_types("dragonfly") def test_mrevrange_latest(r: redis.Redis): timeseries = r.ts() timeseries.create("t1") @@ -631,6 +660,7 @@ def test_mrevrange_latest(r: redis.Redis): ] +@pytest.mark.unsupported_server_types("dragonfly") def test_get(r: redis.Redis): name = "test" r.ts().create(name) @@ -642,6 +672,7 @@ def test_get(r: redis.Redis): @pytest.mark.onlynoncluster +@pytest.mark.unsupported_server_types("dragonfly") def test_get_latest(r: redis.Redis): timeseries = r.ts() timeseries.create("t1") @@ -655,6 +686,7 @@ def test_get_latest(r: redis.Redis): assert timeseries.get("t2", latest=True) == (0, 4.0) +@pytest.mark.unsupported_server_types("dragonfly") def test_mget_errors(r: redis.Redis): r.ts().create(1, labels={"Test": "This"}) r.ts().create(2, labels={"Test": "This", "Taste": "That"}) @@ -667,6 +699,7 @@ def test_mget_errors(r: redis.Redis): assert str(e.value) == "TSDB: failed parsing labels" +@pytest.mark.unsupported_server_types("dragonfly") def test_mget(r: redis.Redis): r.ts().create(1, labels={"Test": "This"}) r.ts().create(2, labels={"Test": "This", "Taste": "That"}) @@ -689,6 +722,7 @@ def test_mget(r: redis.Redis): @pytest.mark.onlynoncluster +@pytest.mark.unsupported_server_types("dragonfly") def test_mget_latest(r: redis.Redis): timeseries = r.ts() timeseries.create("t1") @@ -704,6 +738,7 @@ def test_mget_latest(r: redis.Redis): assert res == [{"t2": [{}, 0, 4.0]}] +@pytest.mark.unsupported_server_types("dragonfly") def test_info(r: redis.Redis): r.ts().create(1, retention_msecs=5, labels={"currentLabel": "currentData"}) info = r.ts().info(1) @@ -711,6 +746,7 @@ def test_info(r: redis.Redis): assert info["labels"]["currentLabel"] == "currentData" +@pytest.mark.unsupported_server_types("dragonfly") def testInfoDuplicatePolicy(r: redis.Redis): r.ts().create(1, retention_msecs=5, labels={"currentLabel": "currentData"}) info = r.ts().info(1) @@ -722,6 +758,7 @@ def testInfoDuplicatePolicy(r: redis.Redis): @pytest.mark.onlynoncluster +@pytest.mark.unsupported_server_types("dragonfly") def test_query_index(r: redis.Redis): r.ts().create(1, labels={"Test": "This"}) r.ts().create(2, labels={"Test": "This", "Taste": "That"}) @@ -730,6 +767,7 @@ def test_query_index(r: redis.Redis): assert r.ts().queryindex(["Taste=That"]) == [2] +@pytest.mark.unsupported_server_types("dragonfly") def test_pipeline(r: redis.Redis): pipeline = r.ts().pipeline() pipeline.create("with_pipeline") @@ -744,6 +782,7 @@ def test_pipeline(r: redis.Redis): assert r.ts().get("with_pipeline")[1] == 99 * 1.1 +@pytest.mark.unsupported_server_types("dragonfly") def test_uncompressed(r: redis.Redis): r.ts().create("compressed") r.ts().create("uncompressed", uncompressed=True) @@ -753,6 +792,7 @@ def test_uncompressed(r: redis.Redis): assert compressed_info["memory_usage"] != uncompressed_info["memory_usage"] +@pytest.mark.unsupported_server_types("dragonfly") def test_create_rule_green(r: redis.Redis): r.ts().create(1) r.ts().create(2) @@ -768,6 +808,7 @@ def test_create_rule_green(r: redis.Redis): assert info["source_key"] == b"1" +@pytest.mark.unsupported_server_types("dragonfly") def test_create_rule_bad_aggregator(r: redis.Redis): r.ts().create(1) r.ts().create(2) @@ -776,12 +817,14 @@ def test_create_rule_bad_aggregator(r: redis.Redis): assert str(e.value) == msgs.TIMESERIES_BAD_AGGREGATION_TYPE +@pytest.mark.unsupported_server_types("dragonfly") def test_create_rule_key_not_exist(r: redis.Redis): with pytest.raises(redis.ResponseError) as e: r.ts().createrule(1, 2, "avg", 100) assert str(e.value) == msgs.TIMESERIES_KEY_DOES_NOT_EXIST +@pytest.mark.unsupported_server_types("dragonfly") def test_create_rule_with_rule_to_dest_key_exists(r: redis.Redis): r.ts().create(1) r.ts().create(2) diff --git a/test/test_stack/test_topk.py b/test/test_stack/test_topk.py index 1ea092d8..26df13dd 100644 --- a/test/test_stack/test_topk.py +++ b/test/test_stack/test_topk.py @@ -4,6 +4,7 @@ topk_tests = pytest.importorskip("probables") +@pytest.mark.unsupported_server_types("dragonfly") def test_topk_incrby(r: redis.Redis): assert r.topk().reserve("topk", 3, 10, 3, 1) assert [None, None, None] == r.topk().incrby("topk", ["bar", "baz", "42"], [3, 6, 2]) @@ -12,6 +13,7 @@ def test_topk_incrby(r: redis.Redis): assert [3, 6, 10, 4, 0] == r.topk().count("topk", "bar", "baz", "42", "xyzzy", 4) +@pytest.mark.unsupported_server_types("dragonfly") def test_topk(r: redis.Redis): # test list with empty buckets assert r.topk().reserve("topk", 3, 50, 4, 0.9) diff --git a/test/test_mixins/test_transactions_commands.py b/test/test_transactions.py similarity index 99% rename from test/test_mixins/test_transactions_commands.py rename to test/test_transactions.py index cc124d51..2733b728 100644 --- a/test/test_mixins/test_transactions_commands.py +++ b/test/test_transactions.py @@ -5,7 +5,7 @@ import redis.client import fakeredis -from .. import testtools +from . import testtools def test_multiple_successful_watch_calls(r: redis.Redis):