push sheeet
Some checks failed
Periodic Merges (6h) / master → staging-nixos (push) Failing after 12m50s
Periodic Merges (6h) / master → staging-next (push) Failing after 12m54s
Periodic Merges (24h) / merge-base(master,staging) → haskell-updates (push) Failing after 11m54s
Periodic Merges (6h) / staging-next → staging (push) Failing after 12m13s
Periodic Merges (24h) / staging-next-25.05 → staging-25.05 (push) Failing after 13m24s
Periodic Merges (24h) / release-25.05 → staging-next-25.05 (push) Failing after 14m28s

This commit is contained in:
Dark Steveneq
2025-10-09 14:15:47 +02:00
commit 646b892680
49168 changed files with 5897842 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
{
lib,
aetcd,
buildPythonPackage,
coredis,
deprecated,
etcd3,
fetchFromGitHub,
flaky,
hiro,
importlib-resources,
motor,
packaging,
pymemcache,
pymongo,
pytest-asyncio,
pytest-benchmark,
pytest-cov-stub,
pytest-lazy-fixtures,
pytestCheckHook,
pythonOlder,
redis,
setuptools,
typing-extensions,
valkey,
}:
buildPythonPackage rec {
pname = "limits";
version = "5.4.0";
pyproject = true;
src = fetchFromGitHub {
owner = "alisaifee";
repo = "limits";
tag = version;
# Upstream uses versioneer, which relies on git attributes substitution.
# This leads to non-reproducible archives on github. Remove the substituted
# file here, and recreate it later based on our version info.
hash = "sha256-EHLqkd5Muazr52/oYaLklFVvF+AzJWGbFaaIG+T0ulE=";
postFetch = ''
rm "$out/limits/_version.py"
'';
};
patches = [
./only-test-in-memory.patch
];
postPatch = ''
substituteInPlace pytest.ini \
--replace-fail "-K" ""
substituteInPlace setup.py \
--replace-fail "versioneer.get_version()" "'${version}'"
# Recreate _version.py, deleted at fetch time due to non-reproducibility.
echo 'def get_versions(): return {"version": "${version}"}' > limits/_version.py
'';
build-system = [ setuptools ];
dependencies = [
deprecated
importlib-resources
packaging
typing-extensions
];
optional-dependencies = {
redis = [ redis ];
rediscluster = [ redis ];
memcached = [ pymemcache ];
mongodb = [ pymongo ];
etcd = [ etcd3 ];
async-redis = [ coredis ];
# async-memcached = [
# emcache # Missing module
# ];
async-mongodb = [ motor ];
async-etcd = [ aetcd ];
valkey = [ valkey ];
};
env = {
# make protobuf compatible with old versions
# https://developers.google.com/protocol-buffers/docs/news/2022-05-06#python-updates
PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION = "python";
};
nativeCheckInputs = [
flaky
hiro
pytest-asyncio
pytest-benchmark
pytest-cov-stub
pytest-lazy-fixtures
pytestCheckHook
]
++ lib.flatten (lib.attrValues optional-dependencies);
pytestFlags = [ "--benchmark-disable" ];
disabledTests = [
"test_moving_window_memcached"
# Flaky: compares time to magic value
"test_sliding_window_counter_previous_window"
];
pythonImportsCheck = [ "limits" ];
meta = {
description = "Rate limiting using various strategies and storage backends such as redis & memcached";
homepage = "https://github.com/alisaifee/limits";
changelog = "https://github.com/alisaifee/limits/releases/tag/${src.tag}";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [ sarahec ];
};
}

View File

@@ -0,0 +1,397 @@
diff --git a/tests/aio/test_storage.py b/tests/aio/test_storage.py
index 43fc5b1..9aa86ed 100644
--- a/tests/aio/test_storage.py
+++ b/tests/aio/test_storage.py
@@ -153,94 +153,6 @@ class TestBaseStorage:
marks=pytest.mark.memory,
id="in-memory",
),
- pytest.param(
- "async+redis://localhost:7379",
- {},
- RedisStorage,
- lf("redis_basic"),
- marks=pytest.mark.redis,
- id="redis",
- ),
- pytest.param(
- "async+redis+unix:///tmp/limits.redis.sock",
- {},
- RedisStorage,
- lf("redis_uds"),
- marks=pytest.mark.redis,
- id="redis-uds",
- ),
- pytest.param(
- "async+redis+unix://:password/tmp/limits.redis.sock",
- {},
- RedisStorage,
- lf("redis_uds"),
- marks=pytest.mark.redis,
- id="redis-uds-auth",
- ),
- pytest.param(
- "async+memcached://localhost:22122",
- {},
- MemcachedStorage,
- lf("memcached"),
- marks=pytest.mark.memcached,
- id="memcached",
- ),
- pytest.param(
- "async+memcached://localhost:22122,localhost:22123",
- {},
- MemcachedStorage,
- lf("memcached_cluster"),
- marks=pytest.mark.memcached,
- id="memcached-cluster",
- ),
- pytest.param(
- "async+redis+sentinel://localhost:26379",
- {"service_name": "mymaster"},
- RedisSentinelStorage,
- lf("redis_sentinel"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel",
- ),
- pytest.param(
- "async+redis+sentinel://localhost:26379/mymaster",
- {},
- RedisSentinelStorage,
- lf("redis_sentinel"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel-service-name-url",
- ),
- pytest.param(
- "async+redis+sentinel://:sekret@localhost:36379/mymaster",
- {"password": "sekret"},
- RedisSentinelStorage,
- lf("redis_sentinel_auth"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel-auth",
- ),
- pytest.param(
- "async+redis+cluster://localhost:7001/",
- {},
- RedisClusterStorage,
- lf("redis_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster",
- ),
- pytest.param(
- "async+redis+cluster://:sekret@localhost:8400/",
- {},
- RedisClusterStorage,
- lf("redis_auth_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster-auth",
- ),
- pytest.param(
- "async+mongodb://localhost:37017/",
- {},
- MongoDBStorage,
- lf("mongodb"),
- marks=pytest.mark.mongodb,
- id="mongodb",
- ),
],
)
class TestConcreteStorages:
diff --git a/tests/test_storage.py b/tests/test_storage.py
index f9698c0..2062e3a 100644
--- a/tests/test_storage.py
+++ b/tests/test_storage.py
@@ -148,102 +148,6 @@ class TestBaseStorage:
"uri, args, expected_instance, fixture",
[
pytest.param("memory://", {}, MemoryStorage, None, id="in-memory"),
- pytest.param(
- "redis://localhost:7379",
- {},
- RedisStorage,
- lf("redis_basic"),
- marks=pytest.mark.redis,
- id="redis",
- ),
- pytest.param(
- "redis+unix:///tmp/limits.redis.sock",
- {},
- RedisStorage,
- lf("redis_uds"),
- marks=pytest.mark.redis,
- id="redis-uds",
- ),
- pytest.param(
- "redis+unix://:password/tmp/limits.redis.sock",
- {},
- RedisStorage,
- lf("redis_uds"),
- marks=pytest.mark.redis,
- id="redis-uds-auth",
- ),
- pytest.param(
- "memcached://localhost:22122",
- {},
- MemcachedStorage,
- lf("memcached"),
- marks=pytest.mark.memcached,
- id="memcached",
- ),
- pytest.param(
- "memcached://localhost:22122,localhost:22123",
- {},
- MemcachedStorage,
- lf("memcached_cluster"),
- marks=pytest.mark.memcached,
- id="memcached-cluster",
- ),
- pytest.param(
- "memcached:///tmp/limits.memcached.sock",
- {},
- MemcachedStorage,
- lf("memcached_uds"),
- marks=pytest.mark.memcached,
- id="memcached-uds",
- ),
- pytest.param(
- "redis+sentinel://localhost:26379",
- {"service_name": "mymaster"},
- RedisSentinelStorage,
- lf("redis_sentinel"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel",
- ),
- pytest.param(
- "redis+sentinel://localhost:26379/mymaster",
- {},
- RedisSentinelStorage,
- lf("redis_sentinel"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel-service-name-url",
- ),
- pytest.param(
- "redis+sentinel://:sekret@localhost:36379/mymaster",
- {"password": "sekret"},
- RedisSentinelStorage,
- lf("redis_sentinel_auth"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel-auth",
- ),
- pytest.param(
- "redis+cluster://localhost:7001/",
- {},
- RedisClusterStorage,
- lf("redis_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster",
- ),
- pytest.param(
- "redis+cluster://:sekret@localhost:8400/",
- {},
- RedisClusterStorage,
- lf("redis_auth_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster-auth",
- ),
- pytest.param(
- "mongodb://localhost:37017/",
- {},
- MongoDBStorage,
- lf("mongodb"),
- marks=pytest.mark.mongodb,
- id="mongodb",
- ),
],
)
class TestConcreteStorages:
diff --git a/tests/utils.py b/tests/utils.py
index 3341bcf..6dc2bc3 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -90,186 +90,11 @@ ALL_STORAGES = {
"memory": pytest.param(
"memory://", {}, None, marks=pytest.mark.memory, id="in-memory"
),
- "redis": pytest.param(
- "redis://localhost:7379",
- {},
- lf("redis_basic"),
- marks=pytest.mark.redis,
- id="redis_basic",
- ),
- "memcached": pytest.param(
- "memcached://localhost:22122",
- {},
- lf("memcached"),
- marks=[pytest.mark.memcached, pytest.mark.flaky],
- id="memcached",
- ),
- "memcached-cluster": pytest.param(
- "memcached://localhost:22122,localhost:22123",
- {},
- lf("memcached_cluster"),
- marks=[pytest.mark.memcached, pytest.mark.flaky],
- id="memcached-cluster",
- ),
- "redis-cluster": pytest.param(
- "redis+cluster://localhost:7001/",
- {},
- lf("redis_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster",
- ),
- "redis-cluster_auth": pytest.param(
- "redis+cluster://:sekret@localhost:8400/",
- {},
- lf("redis_auth_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster-auth",
- ),
- "redis-ssl-cluster": pytest.param(
- "redis+cluster://localhost:8301",
- {
- "ssl": True,
- "ssl_cert_reqs": "required",
- "ssl_keyfile": "./tests/tls/client.key",
- "ssl_certfile": "./tests/tls/client.crt",
- "ssl_ca_certs": "./tests/tls/ca.crt",
- },
- lf("redis_ssl_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-ssl-cluster",
- ),
- "redis-sentinel": pytest.param(
- "redis+sentinel://localhost:26379/mymaster",
- {"use_replicas": False},
- lf("redis_sentinel"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel",
- ),
- "mongodb": pytest.param(
- "mongodb://localhost:37017/",
- {},
- lf("mongodb"),
- marks=pytest.mark.mongodb,
- id="mongodb",
- ),
- "valkey": pytest.param(
- "valkey://localhost:12379",
- {},
- lf("valkey_basic"),
- marks=pytest.mark.valkey,
- id="valkey_basic",
- ),
- "valkey-cluster": pytest.param(
- "valkey+cluster://localhost:2001/",
- {},
- lf("valkey_cluster"),
- marks=pytest.mark.valkey_cluster,
- id="valkey-cluster",
- ),
}
ALL_STORAGES_ASYNC = {
"memory": pytest.param(
"async+memory://", {}, None, marks=pytest.mark.memory, id="in-memory"
),
- "redis": pytest.param(
- "async+redis://localhost:7379",
- {
- "implementation": ASYNC_REDIS_IMPLEMENTATION,
- },
- lf("redis_basic"),
- marks=pytest.mark.redis,
- id="redis",
- ),
- "memcached": pytest.param(
- "async+memcached://localhost:22122",
- {
- "implementation": ASYNC_MEMCACHED_IMPLEMENTATION,
- },
- lf("memcached"),
- marks=[pytest.mark.memcached, pytest.mark.flaky],
- id="memcached",
- ),
- "memcached-cluster": pytest.param(
- "async+memcached://localhost:22122,localhost:22123",
- {
- "implementation": ASYNC_MEMCACHED_IMPLEMENTATION,
- },
- lf("memcached_cluster"),
- marks=[pytest.mark.memcached, pytest.mark.flaky],
- id="memcached-cluster",
- ),
- "memcached-sasl": pytest.param(
- "async+memcached://user:password@localhost:22124",
- {
- "implementation": ASYNC_MEMCACHED_IMPLEMENTATION,
- },
- lf("memcached_sasl"),
- marks=[pytest.mark.memcached, pytest.mark.flaky],
- id="memcached-sasl",
- ),
- "redis-cluster": pytest.param(
- "async+redis+cluster://localhost:7001/",
- {
- "implementation": ASYNC_REDIS_IMPLEMENTATION,
- },
- lf("redis_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster",
- ),
- "redis-cluster-auth": pytest.param(
- "async+redis+cluster://:sekret@localhost:8400/",
- {
- "implementation": ASYNC_REDIS_IMPLEMENTATION,
- },
- lf("redis_auth_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-cluster-auth",
- ),
- "redis-ssl-cluster": pytest.param(
- "async+redis+cluster://localhost:8301",
- {
- "ssl": True,
- "ssl_cert_reqs": "required",
- "ssl_keyfile": "./tests/tls/client.key",
- "ssl_certfile": "./tests/tls/client.crt",
- "ssl_ca_certs": "./tests/tls/ca.crt",
- "implementation": ASYNC_REDIS_IMPLEMENTATION,
- },
- lf("redis_ssl_cluster"),
- marks=pytest.mark.redis_cluster,
- id="redis-ssl-cluster",
- ),
- "redis-sentinel": pytest.param(
- "async+redis+sentinel://localhost:26379/mymaster",
- {
- "use_replicas": False,
- "implementation": ASYNC_REDIS_IMPLEMENTATION,
- },
- lf("redis_sentinel"),
- marks=pytest.mark.redis_sentinel,
- id="redis-sentinel",
- ),
- "mongodb": pytest.param(
- "async+mongodb://localhost:37017/",
- {},
- lf("mongodb"),
- marks=pytest.mark.mongodb,
- id="mongodb",
- ),
- "valkey": pytest.param(
- "async+valkey://localhost:12379",
- {},
- lf("valkey_basic"),
- marks=pytest.mark.valkey,
- id="valkey_basic",
- ),
- "valkey-cluster": pytest.param(
- "async+valkey+cluster://localhost:2001/",
- {},
- lf("valkey_cluster"),
- marks=pytest.mark.valkey_cluster,
- id="valkey-cluster",
- ),
}
all_storage = pytest.mark.parametrize("uri, args, fixture", ALL_STORAGES.values())