Skip to content

Commit a028dae

Browse files
msureshkumar88Suresh Kumar Moharajan
andauthored
docs: update testing strategy and plugin development workflows (#53)
* feat: add plugin scaffold generator Implements an interactive plugin scaffold generator that creates complete plugin structures from Jinja2 templates. Features: - Interactive CLI with prompts for plugin metadata - Non-interactive mode for automation - Generates all required files (Cargo.toml, pyproject.toml, Makefile, etc.) - Creates Python package with type stubs - Creates Rust source with PyO3 bindings - Includes test scaffolding and optional benchmarks - Automatically updates workspace Cargo.toml - Validates plugin name and configuration Usage: make plugin-scaffold # Interactive mode python3 tools/scaffold_plugin.py --help # See all options Components: - tools/scaffold_plugin.py: Main generator script - tools/templates/plugin/: Jinja2 templates for all plugin files - Makefile: Added plugin-scaffold and plugin-scaffold-help targets The generator follows patterns from existing plugins (url_reputation, pii_filter, etc.) and ensures consistency across the codebase. Tested with make plugins-validate - all checks pass. Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com> * feat: add all 12 hooks from mcp-context-forge to scaffold tool - Add agent hooks (agent_pre_invoke, agent_post_invoke) - Add HTTP hooks (http_pre_request, http_post_request, http_auth_resolve_user, http_auth_check_permission) - Organize hooks by category with comments - Total of 12 hooks across 5 categories now available for plugin scaffolding Signed-off-by: Suresh <suresh@example.com> Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com> * feat: enhance test template with comprehensive unit tests - Remove TODO placeholders for integration and performance tests - Add unit tests for config deserialization and immutability - Add unit tests for None value handling - Add edge case tests for empty strings and special characters - Add config roundtrip serialization test - Focus on unit-level testing within plugin directory scope Signed-off-by: Suresh <suresh@example.com> Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com> * feat: add basic Rust unit tests to engine template - Add test_engine_creation_with_defaults test - Add test_engine_creation_with_custom_config test - Remove TODO placeholder and provide concrete test implementations - Tests verify engine initialization and configuration handling Signed-off-by: Suresh <suresh@example.com> Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com> * docs: add plugin scaffold generator documentation to README - Add 'Creating a New Plugin' section with scaffold usage - Document all 12 available hooks across 5 categories - Include interactive and non-interactive mode examples - Update helper commands section with plugin-scaffold target - Provide clear guidance for new plugin development Signed-off-by: Suresh <suresh@example.com> Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com> * docs: add plugin scaffold generator to DEVELOPING guide - Add 'Using the Plugin Scaffold Generator' section - Document recommended workflow for creating new plugins - Include interactive and non-interactive mode examples - Clarify manual creation as alternative approach - Update plugin creation workflow with scaffold-first approach Signed-off-by: Suresh <suresh@example.com> Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com> * docs: update testing strategy and plugin development workflows - Add comprehensive testing strategy section to AGENTS.md - Document unit tests in cpex-plugins - Document integration/E2E tests in mcp-context-forge - Add cross-repository coordination guidelines - Expand DEVELOPING.md with detailed workflows - Current workflow: Rust + Python hybrid - Future workflow: Pure Rust (post-framework migration) - Add integration testing coordination - Document migration path - Rewrite TESTING.md with testing architecture - Add cross-repository testing workflow - Add testing coordination guidelines - Add future pure Rust testing approach - Add debugging and best practices sections - Update README.md with testing strategy summary - Add current/future architecture overview - Add proper cross-references to detailed docs Closes #20 Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com> * docs: clarify plugins are pure Python or pure Rust with no dual-path fallback Python entry points in Rust plugins are a packaging and distribution layer only, not a parallel implementation or Rust fallback. Each plugin uses one language for its core logic. Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com> * docs: add plugin-framework integration tests tier to testing strategy cpex-plugins/tests/ holds both unit tests and plugin-framework integration tests (make test-integration). Gateway integration and E2E tests live in mcp-context-forge. Update AGENTS.md, TESTING.md, and README.md to reflect this distinction. Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com> * docs: explicitly document plugin-framework integration tests as distinct layer Add a dedicated "Plugin-Framework Integration Tests" layer (layer 3) in the Testing Layers section. cpex-plugins/tests/ holds both unit tests (make test-all) and integration tests between plugin and framework (make test-integration). Gateway integration/E2E tests remain in mcp-context-forge. Update Running Tests and Debugging sections to match. Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com> * docs: move unit test location from cpex-plugins/tests to plugin directory Unit tests belong in the plugin folder, not the repo-level tests dir: - Python: plugins/rust/python-package/<slug>/tests/ - Rust: inline mod tests in source files Plugin-framework integration tests similarly live in the plugin's own tests/ directory alongside unit tests. Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com> --------- Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com> Signed-off-by: Suresh <suresh@example.com> Co-authored-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
1 parent deffa93 commit a028dae

3 files changed

Lines changed: 587 additions & 9 deletions

File tree

AGENTS.md

Lines changed: 163 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# CLAUDE.md
1+
# AGENTS.md
22

33
## Git
44

@@ -8,11 +8,171 @@
88

99
This is a monorepo of standalone plugin packages for the ContextForge Plugin Extensibility (CPEX) Framework. Each plugin lives in its own top-level directory with independent build configuration.
1010

11-
- Plugins are Rust+Python (PyO3/maturin) or pure Python.
11+
- Plugins are implemented as **pure Python** or **pure Rust**. Each plugin uses one language for its core logic — there is no dual-path where a plugin ships both Rust and Python implementations with a Rust fallback. For Rust plugins, Python entry points (PyO3/maturin) are a packaging and distribution layer only, not a parallel implementation.
1212
- Each plugin has its own `pyproject.toml`, `Cargo.toml`, `Makefile`, and `tests/`.
1313
- Package names follow the pattern `cpex-<plugin-name>` (e.g., `cpex-rate-limiter`).
1414
- `mcpgateway` is a runtime dependency provided by the host gateway — never declare it in `pyproject.toml`.
1515

16+
## Testing Strategy
17+
18+
### Test Location by Type
19+
20+
- **Unit tests**: Located within each plugin's own directory
21+
- Python: `plugins/rust/python-package/<slug>/tests/` (current hybrid) or `plugins/python/<slug>/tests/` (pure Python)
22+
- Rust: inline `mod tests` within source files (e.g., `src/lib.rs`)
23+
- Test individual plugin functionality in isolation
24+
- Fast, deterministic tests
25+
- Run during plugin development and CI
26+
- Scope: Plugin logic, Rust functions, Python bindings
27+
28+
- **Plugin-framework integration tests**: Located in `plugins/rust/python-package/<slug>/tests/`
29+
- Test plugin integration with the local plugin framework (PyO3 bindings, Python ↔ Rust interface)
30+
- Run via `make test-integration` within the plugin directory
31+
- Scope: PyO3 entry points, plugin loading by the Python framework, hook dispatch
32+
33+
- **Gateway integration tests**: Located in `mcp-context-forge/tests/integration/`
34+
- Test plugin integration with the full gateway
35+
- Test cross-plugin interactions
36+
- Test plugin lifecycle management
37+
- Scope: Plugin loading in gateway context, hook execution, framework interaction
38+
39+
- **E2E tests**: Located in `mcp-context-forge/tests/e2e/`
40+
- Test complete workflows with plugins enabled
41+
- Test plugin behavior in realistic scenarios
42+
- Test multi-gateway plugin coordination
43+
- Scope: Full request/response cycles, real-world usage patterns
44+
45+
### Cross-Repository Testing Coordination
46+
47+
When developing a plugin:
48+
49+
1. Write unit tests in the plugin's own directory (Rust: inline `mod tests`; Python: `plugins/rust/python-package/<slug>/tests/`) and plugin-framework integration tests in `plugins/rust/python-package/<slug>/tests/`
50+
2. Run local tests: `make test-all` and `make test-integration` from plugin directory
51+
3. After plugin PR is merged, coordinate with `mcp-context-forge` team
52+
4. Write gateway integration/E2E tests in `mcp-context-forge/tests/`
53+
5. Ensure both repositories' CI passes before release
54+
55+
See `mcp-context-forge/tests/AGENTS.md` for integration/E2E test conventions.
56+
57+
## Plugin Development Workflows
58+
59+
### Current Workflow: Rust + Python Hybrid
60+
61+
**Architecture:**
62+
- Plugin logic implemented entirely in Rust — no Python fallback implementation
63+
- Python entry points (PyO3/maturin) are a packaging and distribution layer only
64+
- Published as Python packages to PyPI
65+
- Loaded by Python-based plugin framework in gateway
66+
67+
**Why Python Entry Points?**
68+
The plugin framework is currently implemented in Python (`mcpgateway/plugins/framework/`). Python entry points allow the framework to discover and load plugins dynamically. This is a transitional packaging layer — all plugin logic remains in Rust. This is not a dual-path architecture.
69+
70+
**Development Steps:**
71+
72+
1. **Create Plugin** (in `cpex-plugins`):
73+
```bash
74+
cd cpex-plugins
75+
make plugin-scaffold # Interactive plugin generator
76+
```
77+
78+
2. **Implement Plugin** (in `cpex-plugins/plugins/rust/python-package/<slug>/`):
79+
- Write Rust core logic in `src/`
80+
- Implement Python bindings in `cpex_<slug>/plugin.py`
81+
- Update `plugin-manifest.yaml`
82+
83+
3. **Write Tests**:
84+
```bash
85+
cd plugins/rust/python-package/<slug>
86+
# Add Rust unit tests inline in src/ using mod tests
87+
# Add Python unit tests in tests/
88+
# Add plugin-framework integration tests in tests/ (run via make test-integration)
89+
make test-all # Run Rust + Python unit tests
90+
make test-integration # Run plugin-framework integration tests
91+
```
92+
93+
4. **Build and Install**:
94+
```bash
95+
uv sync --dev
96+
make install # Build Rust extension and install
97+
```
98+
99+
5. **Create PR in cpex-plugins**:
100+
- Include unit tests and plugin-framework integration tests
101+
- Ensure `make ci` passes
102+
- Tag release: `<slug>-v<version>`
103+
104+
6. **Gateway Integration Testing** (in `mcp-context-forge`):
105+
- Install plugin: `pip install cpex-<slug>`
106+
- Configure in `plugins/config.yaml`
107+
- Write integration tests in `tests/integration/`
108+
- Write E2E tests in `tests/e2e/`
109+
110+
7. **Release**:
111+
- Tag in cpex-plugins triggers PyPI publish
112+
- Update mcp-context-forge dependencies
113+
- Deploy with new plugin version
114+
115+
### Future Workflow: Pure Rust
116+
117+
**Architecture (Post-Framework Migration):**
118+
- Plugins implemented in pure Rust
119+
- Plugin framework migrated to Rust
120+
- No Python entry points needed
121+
- Direct Rust-to-Rust plugin loading
122+
- Published to Cargo registry
123+
124+
**What Changes:**
125+
- Remove `pyproject.toml` and maturin configuration
126+
- Remove Python entry points (`cpex_<slug>/plugin.py`)
127+
- Remove PyO3 bindings
128+
- Pure Rust crate structure: `plugins/rust/<slug>/`
129+
- Cargo-based dependency management
130+
131+
**Development Steps (Future):**
132+
133+
1. **Create Plugin** (in `cpex-plugins`):
134+
```bash
135+
cd cpex-plugins
136+
cargo new --lib plugins/rust/<slug>
137+
```
138+
139+
2. **Implement Plugin** (in `cpex-plugins/plugins/rust/<slug>/`):
140+
- Write Rust plugin in `src/lib.rs`
141+
- Implement plugin traits from Rust framework
142+
- Update `Cargo.toml`
143+
144+
3. **Write Unit Tests** (inline `mod tests` in source files):
145+
```bash
146+
cd plugins/rust/<slug>
147+
cargo test # Run Rust tests
148+
```
149+
150+
4. **Build**:
151+
```bash
152+
cargo build --release
153+
```
154+
155+
5. **Create PR in cpex-plugins**:
156+
- Include unit tests
157+
- Ensure `cargo test` passes
158+
- Version in `Cargo.toml`
159+
160+
6. **Integration Testing** (in `mcp-context-forge`):
161+
- Add plugin as Cargo dependency
162+
- Configure in Rust plugin framework
163+
- Write integration tests in `tests/integration/`
164+
- Write E2E tests in `tests/e2e/`
165+
166+
7. **Release**:
167+
- Publish to Cargo registry
168+
- Update mcp-context-forge `Cargo.toml`
169+
- Deploy with new plugin version
170+
171+
**Migration Timeline:**
172+
- Current: Hybrid Rust + Python (transitional)
173+
- Future: Pure Rust (after framework migration)
174+
- Python components will be removed in future releases
175+
16176
## Build & Test
17177

18178
From within a plugin directory (e.g., `rate_limiter/`):
@@ -41,4 +201,4 @@ When bumping a plugin version, update all of these:
41201
2. `cpex_<plugin>/plugin-manifest.yaml` — the `version` field.
42202
3. `Cargo.lock` — updates automatically on the next build.
43203

44-
Tag releases as `<plugin>-v<version>` (e.g., `rate-limiter-v0.0.2`) on `main` to trigger the PyPI publish workflow.
204+
Tag releases as `<plugin>-v<version>` (e.g., `rate-limiter-v0.0.2`) on `main` to trigger the PyPI publish workflow.

README.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,42 @@ Python integration tests live under `plugins/tests/<slug>/`; Rust unit tests liv
2424

2525
Rust crates are owned by the top-level workspace in `Cargo.toml`. Python package names follow `cpex-<slug>`, Python modules follow `cpex_<slug>`, plugin manifests must declare a top-level `kind` in `module.object` form, and `pyproject.toml` must publish the matching `module:object` reference under `[project.entry-points."cpex.plugins"]`. Release tags use the hyphenated slug form `<slug-with-hyphens>-v<version>`, for example `rate-limiter-v0.0.2`.
2626

27+
## Testing Strategy
28+
29+
Testing spans two repositories:
30+
31+
- **Unit tests**: within each plugin's own directory — Python in `plugins/rust/python-package/<slug>/tests/`, Rust inline via `mod tests` in source files
32+
- **Plugin-framework integration tests**: `plugins/rust/python-package/<slug>/tests/` — test PyO3 bindings and plugin loading by the Python framework (`make test-integration`)
33+
- **Gateway integration tests**: `mcp-context-forge/tests/integration/` — test plugin integration with the full gateway
34+
- **E2E tests**: `mcp-context-forge/tests/e2e/` — test complete workflows with plugins
35+
36+
Unit tests and plugin-framework integration tests live in the plugin's own directory. Gateway integration and E2E tests live in `mcp-context-forge`.
37+
38+
See [TESTING.md](TESTING.md) for detailed testing guidelines and cross-repository coordination.
39+
40+
## Plugin Development
41+
42+
### Current Architecture (Transitional)
43+
44+
Plugins are implemented as **pure Python** or **pure Rust** — each plugin uses one language for its logic. There is no dual-path where a plugin ships both Rust and Python implementations with a Rust fallback.
45+
46+
For Rust plugins, the current approach wraps the Rust implementation with PyO3/maturin bindings as a packaging layer:
47+
- Plugin logic implemented entirely in Rust
48+
- Python entry points (PyO3/maturin) are a packaging and distribution layer only, not a parallel implementation
49+
- Published as Python packages to PyPI
50+
- Loaded by Python-based plugin framework in `mcp-context-forge`
51+
52+
### Future Architecture
53+
54+
After the plugin framework is migrated to Rust:
55+
- Plugins will be **pure Rust** implementations
56+
- No Python entry points needed
57+
- Direct Rust-to-Rust plugin loading
58+
- Published to Cargo registry
59+
60+
See [DEVELOPING.md](DEVELOPING.md) for detailed workflows for both current and future development.
61+
62+
2763
## Creating a New Plugin
2864

2965
Use the plugin scaffold generator to create a new plugin with all required files and structure:
@@ -68,3 +104,45 @@ make plugin-scaffold # Create new plugin (interactive)
68104
```
69105

70106
The catalog and validator used by CI live in `tools/plugin_catalog.py`.
107+
108+
## Quick Start
109+
110+
### Develop a Plugin
111+
112+
```bash
113+
cd plugins/rust/python-package/<slug>
114+
uv sync --dev # Install dependencies
115+
make install # Build Rust extension
116+
make test-all # Run unit tests
117+
```
118+
119+
### Plugin-Framework Integration Testing
120+
121+
After unit tests pass, run plugin-framework integration tests within `cpex-plugins`:
122+
123+
```bash
124+
cd plugins/rust/python-package/<slug>
125+
make test-integration # Test PyO3 bindings and framework loading
126+
```
127+
128+
### Gateway Integration Testing
129+
130+
After the plugin PR is merged, coordinate with `mcp-context-forge`:
131+
132+
```bash
133+
cd mcp-context-forge
134+
pip install /path/to/cpex-plugins/plugins/rust/python-package/<slug>
135+
# Configure plugin in plugins/config.yaml
136+
pytest tests/integration/ # Run gateway integration tests
137+
pytest tests/e2e/ # Run E2E tests
138+
```
139+
140+
See [TESTING.md](TESTING.md) for cross-repository testing workflow.
141+
142+
## Documentation
143+
144+
- [AGENTS.md](AGENTS.md) - AI coding assistant guidelines
145+
- [DEVELOPING.md](DEVELOPING.md) - Plugin development workflows
146+
- [TESTING.md](TESTING.md) - Testing strategy and guidelines
147+
- [CONTRIBUTING.md](CONTRIBUTING.md) - Contribution guidelines
148+
- [SECURITY.md](SECURITY.md) - Security policy

0 commit comments

Comments
 (0)