Skip to content

Commit 751be5b

Browse files
committed
fix(ci): align plugin tests with PyPI migration
Signed-off-by: lucarlig <luca.carlig@ibm.com>
1 parent 2e29125 commit 751be5b

15 files changed

Lines changed: 493 additions & 1426 deletions

.secrets.baseline

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"files": "^.secrets.baseline$|package-lock.json|Cargo.lock|scripts/sign_image.sh|scripts/zap|sonar-project.properties|uv.lock",
44
"lines": null
55
},
6-
"generated_at": "2026-04-10T00:00:12Z",
6+
"generated_at": "2026-04-10T10:32:47Z",
77
"plugins_used": [
88
{
99
"name": "AWSKeyDetector"
@@ -8604,7 +8604,7 @@
86048604
"hashed_secret": "25910f981e85ca04baf359199dd0bd4a3ae738b6",
86058605
"is_secret": false,
86068606
"is_verified": false,
8607-
"line_number": 505,
8607+
"line_number": 451,
86088608
"type": "AWS Access Key",
86098609
"verified_result": null
86108610
}
@@ -11260,47 +11260,47 @@
1126011260
"hashed_secret": "55d2534ed6ad4f269b428160428fa2f6f541ba7b",
1126111261
"is_secret": false,
1126211262
"is_verified": false,
11263-
"line_number": 156,
11263+
"line_number": 136,
1126411264
"type": "Base64 High Entropy String",
1126511265
"verified_result": null
1126611266
},
1126711267
{
1126811268
"hashed_secret": "cf743b3a58a4d0f91c1d7f5825c0b1b5f7758174",
1126911269
"is_secret": false,
1127011270
"is_verified": false,
11271-
"line_number": 538,
11271+
"line_number": 504,
1127211272
"type": "Base64 High Entropy String",
1127311273
"verified_result": null
1127411274
},
1127511275
{
1127611276
"hashed_secret": "8e42b03e460b2cf358ffbcf4da3bc5d14a22c86e",
1127711277
"is_secret": false,
1127811278
"is_verified": false,
11279-
"line_number": 582,
11279+
"line_number": 548,
1128011280
"type": "Base64 High Entropy String",
1128111281
"verified_result": null
1128211282
},
1128311283
{
1128411284
"hashed_secret": "2093dd9cf307518cfe1d2fa5a3985d6fec4e995e",
1128511285
"is_secret": false,
1128611286
"is_verified": false,
11287-
"line_number": 595,
11287+
"line_number": 561,
1128811288
"type": "Base64 High Entropy String",
1128911289
"verified_result": null
1129011290
},
1129111291
{
1129211292
"hashed_secret": "caa924f200b35ceb6f0e33878faff75203bdccb4",
1129311293
"is_secret": false,
1129411294
"is_verified": false,
11295-
"line_number": 971,
11295+
"line_number": 930,
1129611296
"type": "Secret Keyword",
1129711297
"verified_result": null
1129811298
},
1129911299
{
1130011300
"hashed_secret": "f16da2820437f3c703ff5b95c813f310ce8e67a4",
1130111301
"is_secret": false,
1130211302
"is_verified": false,
11303-
"line_number": 1288,
11303+
"line_number": 1179,
1130411304
"type": "Secret Keyword",
1130511305
"verified_result": null
1130611306
}
@@ -11320,7 +11320,7 @@
1132011320
"hashed_secret": "86de8c52637ec530fe39b0a8471da9b8764d5242",
1132111321
"is_secret": false,
1132211322
"is_verified": false,
11323-
"line_number": 665,
11323+
"line_number": 541,
1132411324
"type": "AWS Access Key",
1132511325
"verified_result": null
1132611326
}

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ recursive-include tests/manual *.py *.md
9494
recursive-include plugins *.py
9595
recursive-include plugins *.json
9696
recursive-include plugins *.sh
97+
recursive-include plugins *.txt
9798
recursive-include plugins *.yaml
9899
recursive-include plugins *.md
99100

tests/integration/test_encoded_exfil.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
ToolHookType,
1717
ToolPostInvokePayload,
1818
)
19-
from plugins.encoded_exfil_detection.encoded_exfil_detector import (
19+
from cpex_encoded_exfil_detection.encoded_exfil_detection import (
2020
EncodedExfilDetectorPlugin,
2121
)
2222

@@ -26,7 +26,7 @@ def _make_plugin(config: dict, mode: str = "enforce") -> EncodedExfilDetectorPlu
2626
return EncodedExfilDetectorPlugin(
2727
PluginConfig(
2828
name="EncodedExfilDetector",
29-
kind="plugins.encoded_exfil_detection.encoded_exfil_detector.EncodedExfilDetectorPlugin",
29+
kind="cpex_encoded_exfil_detection.encoded_exfil_detection.EncodedExfilDetectorPlugin",
3030
hooks=[PromptHookType.PROMPT_PRE_FETCH, ToolHookType.TOOL_POST_INVOKE],
3131
mode=mode,
3232
config=config,

tests/integration/test_rate_limiter.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
from mcpgateway.plugins.framework.errors import PluginViolationError
4444
from mcpgateway.plugins.framework.manager import PluginExecutor
4545
from mcpgateway.plugins.framework.models import PluginMode
46-
from plugins.rate_limiter.rate_limiter import RateLimiterPlugin
46+
from cpex_rate_limiter.rate_limiter import RateLimiterPlugin
4747

4848
# API Endpoints
4949
PROMPT_ENDPOINT = "/api/v1/prompts/"
@@ -55,7 +55,7 @@ def rate_limit_plugin_2_per_second():
5555
"""Rate limiter plugin configured for 2 requests per second."""
5656
config = PluginConfig(
5757
name="RateLimiter",
58-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
58+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
5959
hooks=["prompt_pre_fetch", "tool_pre_invoke"],
6060
priority=100,
6161
config={"by_user": "2/s", "by_tenant": None, "by_tool": {}},
@@ -68,7 +68,7 @@ def rate_limit_plugin_multi_dimensional():
6868
"""Rate limiter plugin with multi-dimensional limits."""
6969
config = PluginConfig(
7070
name="RateLimiter",
71-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
71+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
7272
hooks=["prompt_pre_fetch", "tool_pre_invoke"],
7373
priority=100,
7474
config={"by_user": "10/s", "by_tenant": "5/s", "by_tool": {"restricted_tool": "1/s"}},
@@ -243,7 +243,7 @@ async def test_user_rate_limit_enforced(self):
243243
# Configure with ONLY user limits (no tenant limit)
244244
config = PluginConfig(
245245
name="RateLimiter",
246-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
246+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
247247
hooks=["prompt_pre_fetch"],
248248
priority=100,
249249
config={"by_user": "10/s", "by_tenant": None, "by_tool": {}}, # No tenant limit
@@ -318,7 +318,7 @@ async def test_most_restrictive_dimension_selected(self):
318318
# Configure with different limits
319319
config = PluginConfig(
320320
name="RateLimiter",
321-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
321+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
322322
hooks=["prompt_pre_fetch"],
323323
priority=100,
324324
config={
@@ -424,7 +424,7 @@ class TestSlidingWindowIntegration:
424424
def plugin(self):
425425
config = PluginConfig(
426426
name="RateLimiter",
427-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
427+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
428428
hooks=["prompt_pre_fetch", "tool_pre_invoke"],
429429
priority=100,
430430
config={"by_user": "3/s", "algorithm": "sliding_window"},
@@ -513,7 +513,7 @@ class TestTokenBucketIntegration:
513513
def plugin(self):
514514
config = PluginConfig(
515515
name="RateLimiter",
516-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
516+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
517517
hooks=["prompt_pre_fetch", "tool_pre_invoke"],
518518
priority=100,
519519
config={"by_user": "3/s", "algorithm": "token_bucket"},
@@ -606,7 +606,7 @@ class TestCrossHookSharing:
606606
def plugin(self):
607607
config = PluginConfig(
608608
name="RateLimiter",
609-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
609+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
610610
hooks=["prompt_pre_fetch", "tool_pre_invoke"],
611611
priority=100,
612612
config={"by_user": "5/s"},
@@ -654,7 +654,7 @@ async def test_tenant_counter_shared_across_hooks_and_users(self, plugin):
654654
"""Tenant bucket is shared across all users in the same tenant, regardless of hook."""
655655
config = PluginConfig(
656656
name="RateLimiter",
657-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
657+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
658658
hooks=["prompt_pre_fetch", "tool_pre_invoke"],
659659
priority=100,
660660
config={"by_user": "10/s", "by_tenant": "4/s"},
@@ -687,7 +687,7 @@ class TestPermissiveMode:
687687
def _make_plugin_and_hook(self, limit: str) -> tuple:
688688
config = PluginConfig(
689689
name="RateLimiter",
690-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
690+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
691691
hooks=["tool_pre_invoke"],
692692
priority=100,
693693
mode=PluginMode.PERMISSIVE,
@@ -737,7 +737,7 @@ async def test_permissive_mode_contrast_with_enforce(self):
737737
"""Enforce mode raises PluginViolationError; permissive mode does not."""
738738
enforce_config = PluginConfig(
739739
name="RateLimiter",
740-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
740+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
741741
hooks=["tool_pre_invoke"],
742742
config={"by_user": "1/s"},
743743
mode=PluginMode.ENFORCE,
@@ -764,7 +764,7 @@ class TestDisabledMode:
764764
def _make_plugin_and_refs(self) -> tuple:
765765
config = PluginConfig(
766766
name="RateLimiter",
767-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
767+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
768768
hooks=["tool_pre_invoke"],
769769
priority=100,
770770
mode=PluginMode.DISABLED,
@@ -819,7 +819,7 @@ class TestTenantIsolation:
819819
def plugin(self):
820820
config = PluginConfig(
821821
name="RateLimiter",
822-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
822+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
823823
hooks=["tool_pre_invoke"],
824824
priority=100,
825825
config={"by_user": "3/s", "by_tenant": "5/s"},
@@ -907,7 +907,7 @@ async def test_none_tenant_id_skips_by_tenant_entirely(self):
907907
"""
908908
config = PluginConfig(
909909
name="RateLimiter",
910-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
910+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
911911
hooks=["tool_pre_invoke"],
912912
priority=100,
913913
config={"by_user": "100/s", "by_tenant": "5/s"},
@@ -953,7 +953,7 @@ async def test_explicit_tenant_scopes_correctly_after_fix(self):
953953
"""
954954
config = PluginConfig(
955955
name="RateLimiter",
956-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
956+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
957957
hooks=["tool_pre_invoke"],
958958
priority=100,
959959
config={"by_user": "100/s", "by_tenant": "5/s"},
@@ -982,7 +982,7 @@ async def test_no_limits_configured_allows_all_requests(self):
982982
"""Plugin with all dimensions None must allow every request without tracking."""
983983
config = PluginConfig(
984984
name="RateLimiter",
985-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
985+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
986986
hooks=["tool_pre_invoke"],
987987
config={}, # no by_user, no by_tenant, no by_tool
988988
)
@@ -999,7 +999,7 @@ async def test_no_limits_configured_returns_no_headers(self):
999999
"""Plugin with no configured limits must not set X-RateLimit-* headers."""
10001000
config = PluginConfig(
10011001
name="RateLimiter",
1002-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
1002+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
10031003
hooks=["tool_pre_invoke"],
10041004
config={},
10051005
)
@@ -1015,7 +1015,7 @@ async def test_none_user_defaults_to_anonymous_bucket(self):
10151015
"""user=None in GlobalContext must fall back to 'anonymous' as the rate limit key."""
10161016
config = PluginConfig(
10171017
name="RateLimiter",
1018-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
1018+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
10191019
hooks=["tool_pre_invoke"],
10201020
config={"by_user": "2/s"},
10211021
)
@@ -1038,7 +1038,7 @@ async def test_none_tenant_id_skips_by_tenant_check(self):
10381038
"""tenant_id=None in GlobalContext must skip the by_tenant check entirely — no 'default' bucket."""
10391039
config = PluginConfig(
10401040
name="RateLimiter",
1041-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
1041+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
10421042
hooks=["tool_pre_invoke"],
10431043
config={"by_tenant": "2/s"},
10441044
)
@@ -1059,7 +1059,7 @@ async def test_both_user_and_tenant_none_still_enforces(self):
10591059
"""With both user=None and tenant_id=None the plugin must still enforce limits."""
10601060
config = PluginConfig(
10611061
name="RateLimiter",
1062-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
1062+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
10631063
hooks=["tool_pre_invoke"],
10641064
config={"by_user": "2/s", "by_tenant": "10/s"},
10651065
)
@@ -1081,7 +1081,7 @@ def make_plugin():
10811081
return RateLimiterPlugin(
10821082
PluginConfig(
10831083
name="RateLimiter",
1084-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
1084+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
10851085
hooks=["tool_pre_invoke"],
10861086
config={"by_user": "2/s"},
10871087
)
@@ -1175,7 +1175,7 @@ def _make_redis_plugin(redis_url: str, algorithm: str = "fixed_window", limit: s
11751175
return RateLimiterPlugin(
11761176
PluginConfig(
11771177
name="RateLimiter",
1178-
kind="plugins.rate_limiter.rate_limiter.RateLimiterPlugin",
1178+
kind="cpex_rate_limiter.rate_limiter.RateLimiterPlugin",
11791179
hooks=["tool_pre_invoke"],
11801180
priority=100,
11811181
config={

tests/performance/PLUGIN_PROFILING.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
This guide explains how to use the plugin performance profiling tool in `test_plugins_performance.py`.
44

5+
## Prerequisites
6+
7+
The profiling config (`tests/performance/plugins/config.yaml`) references several plugins from the `[plugins]` extra (`cpex-pii-filter`, `cpex-rate-limiter`, `cpex-retry-with-backoff`, `cpex-secrets-detection`, `cpex-url-reputation`). Install them before running the profiler:
8+
9+
```bash
10+
pip install -e '.[plugins]'
11+
```
12+
13+
If any of these packages are missing, the script will print a clear "skipping plugin perf profiling" message naming the missing packages and exit cleanly without producing any profile files.
14+
515
## Quick Start
616

717
### Run with Summary Table Only (Default)

0 commit comments

Comments
 (0)