-
Notifications
You must be signed in to change notification settings - Fork 1
Feature/mcb metrics removal and test cleanup #153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5f0d1bb
68a97b3
8627258
9d9692a
ff7fa41
693bb68
b6575a4
15c4c6b
af36ffe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| [package] | ||
| name = "mcb-ast-utils" | ||
| description = "AST traversal and analysis utilities for MCP Context Browser" | ||
| homepage.workspace = true | ||
| authors.workspace = true | ||
| repository.workspace = true | ||
| license.workspace = true | ||
| version.workspace = true | ||
| edition.workspace = true | ||
| rust-version.workspace = true | ||
|
|
||
|
|
||
| [lints] | ||
| workspace = true | ||
|
|
||
| [dependencies] | ||
| # Language support for language identification | ||
| mcb-language-support = { path = "../mcb-language-support" } | ||
|
|
||
| # Tree-sitter for direct AST access | ||
| tree-sitter.workspace = true | ||
| tree-sitter-rust.workspace = true | ||
| tree-sitter-python.workspace = true | ||
| tree-sitter-javascript.workspace = true | ||
| tree-sitter-typescript.workspace = true | ||
| tree-sitter-go.workspace = true | ||
| tree-sitter-java.workspace = true | ||
| tree-sitter-c.workspace = true | ||
| tree-sitter-cpp.workspace = true | ||
| tree-sitter-kotlin-ng.workspace = true | ||
|
|
||
| # Error handling | ||
| thiserror.workspace = true | ||
|
|
||
| [dev-dependencies] | ||
| tempfile.workspace = true | ||
| rstest = { workspace = true } | ||
| mockall = { workspace = true } | ||
| insta = { workspace = true } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,23 +18,34 @@ path = "src/lib.rs" | |
| [dependencies] | ||
| # Domain layer - core business logic and port traits | ||
| mcb-domain = { path = "../mcb-domain" } | ||
| mcb-utils = { path = "../mcb-utils" } | ||
|
|
||
| # Application layer - use cases and business logic orchestration | ||
| mcb-application = { path = "../mcb-application" } | ||
|
|
||
| # Core async runtime | ||
| tokio = { workspace = true } | ||
|
|
||
| # Serialization | ||
| serde = { workspace = true } | ||
| serde_json = { workspace = true } | ||
| serde_yaml = { workspace = true } | ||
|
Comment on lines
27
to
-29
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 5. Infrastructure deps removed used crates/mcb-infrastructure/Cargo.toml removes serde_yaml, mcb-utils, and linkme, but mcb-infrastructure still uses serde_yaml for YAML parsing and uses a domain macro that expands to #[linkme::distributed_slice], causing compilation failures. Agent Prompt
|
||
|
|
||
| # Error handling | ||
| anyhow = { workspace = true } | ||
| thiserror = { workspace = true } | ||
|
|
||
| # Logging | ||
| tracing = { workspace = true } | ||
| tracing-subscriber = { workspace = true } | ||
|
|
||
| # Configuration | ||
| figment = { workspace = true } | ||
| toml = { workspace = true } | ||
| notify = { workspace = true } | ||
| arc-swap = { workspace = true } | ||
|
|
||
| # HTTP client | ||
| reqwest = { workspace = true } | ||
|
|
||
| # CLI | ||
| clap = { workspace = true } | ||
|
|
||
|
|
@@ -47,10 +58,15 @@ regex = { workspace = true } | |
| # Date/time handling | ||
| chrono = { workspace = true } | ||
|
|
||
| # Template engines | ||
| handlebars = { workspace = true } | ||
|
|
||
| # Cryptography | ||
| aes-gcm = { workspace = true } | ||
| rand = { workspace = true } | ||
|
|
||
| # Authentication | ||
| bcrypt = { workspace = true } | ||
| argon2 = { workspace = true } | ||
| base64 = { workspace = true } | ||
|
|
||
|
|
@@ -60,6 +76,10 @@ hex = { workspace = true } | |
|
|
||
| # Utilities | ||
| uuid = { workspace = true } | ||
| dirs = { workspace = true } | ||
|
|
||
| # System metrics | ||
| sysinfo = { workspace = true } | ||
|
|
||
| # Fast globbing | ||
| glob = { workspace = true } | ||
|
|
@@ -69,31 +89,48 @@ ignore = { workspace = true } | |
|
|
||
| # Concurrent processing | ||
| futures = { workspace = true } | ||
| rayon = { workspace = true } | ||
|
|
||
| # Text processing | ||
| unicode-segmentation = { workspace = true } | ||
|
|
||
| # Schema generation for MCP | ||
| schemars = { workspace = true } | ||
|
|
||
| # Input validation | ||
| validator = { workspace = true } | ||
|
|
||
| # MCP SDK | ||
| rmcp = { workspace = true } | ||
|
|
||
| # Advanced Multi-Provider Strategy | ||
| tokio-util = { workspace = true } | ||
| dashmap = { workspace = true } | ||
| health = { workspace = true } | ||
|
|
||
| # Additional dependencies | ||
| async-trait = { workspace = true } | ||
| downcast-rs = { workspace = true } | ||
| futures-util = { workspace = true } | ||
| linkme.workspace = true | ||
|
|
||
| # Dependency Injection (IoC Container) | ||
| dill = { workspace = true } | ||
|
|
||
| # Service layer improvements | ||
| itertools = { workspace = true } | ||
| humantime = { workspace = true } | ||
|
|
||
| # Shell expansion | ||
| shellexpand = { workspace = true } | ||
|
|
||
| # Additional crypto | ||
| pbkdf2 = { workspace = true } | ||
| hmac = { workspace = true } | ||
|
|
||
| # SeaORM (database layer) | ||
| sea-orm = { workspace = true } | ||
| sea-orm-migration = { workspace = true } | ||
| # Logging appenders | ||
| tracing-appender = { workspace = true } | ||
|
|
||
| # SQLite for legacy/direct queries | ||
| # SQLite for file hash storage (Phase 3: Incremental indexing) | ||
| sqlx = { workspace = true } | ||
|
|
||
| # Syntax highlighting | ||
|
|
@@ -111,29 +148,20 @@ tree-sitter-ruby = { workspace = true } | |
| tree-sitter-php = { workspace = true } | ||
| tree-sitter-swift = { workspace = true } | ||
|
|
||
| [features] | ||
| default = [] | ||
| test-utils = [] | ||
| # Links providers into linkme distributed slices | ||
| mcb-providers = { path = "../mcb-providers" } | ||
|
|
||
| # Architecture validation (for MCP tool integration) | ||
| mcb-validate = { path = "../mcb-validate" } | ||
|
|
||
| [lints] | ||
| workspace = true | ||
|
|
||
| [dev-dependencies] | ||
| mcb-domain = { path = "../mcb-domain", features = ["test-utils"] } | ||
| mcb-utils = { path = "../mcb-utils" } | ||
| tempfile = { workspace = true } | ||
| toml = { workspace = true } | ||
| tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } | ||
| serial_test = { workspace = true } | ||
| rstest = { workspace = true } | ||
| mockall = { workspace = true } | ||
| mcb-validate = { path = "../mcb-validate" } | ||
| insta = { workspace = true } | ||
|
|
||
| [[test]] | ||
| name = "unit" | ||
| path = "tests/unit/mod.rs" | ||
|
|
||
| [[test]] | ||
| name = "integration" | ||
| path = "tests/integration/mod.rs" | ||
| mcb-domain = { path = "../mcb-domain", features = ["test-utils"] } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,202 @@ | ||
| //! Tests verifying Figment configuration pattern compliance (ADR-025) | ||
| //! | ||
| //! These tests ensure the configuration system adheres to ADR-025 principles: | ||
| //! - All configuration flows through Figment | ||
| //! - Environment variables use `MCP__` prefix (double underscore) | ||
| //! - No implicit fallbacks or legacy `MCB_` prefix support | ||
| //! - Fail-fast on missing required configuration | ||
| //! | ||
| //! # Safety | ||
| //! | ||
| //! Tests use `unsafe` blocks for `env::set_var`/`env::remove_var` because | ||
| //! Rust 2024 edition requires this for environment variable mutations. | ||
| //! Tests use `#[serial]` to prevent data races between env var mutations. | ||
|
|
||
| use std::env; | ||
|
|
||
| use mcb_infrastructure::config::loader::ConfigLoader; | ||
| use serial_test::serial; | ||
|
|
||
| /// Helper to set env var safely. | ||
| #[allow(unsafe_code)] | ||
| fn set_env(key: &str, value: &str) { | ||
|
Comment on lines
+20
to
22
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1. #[allow(unsafe_code)] lacks justification #[allow(unsafe_code)] is used without an inline justification comment on the same line or immediately following line. This violates the requirement to document why a static-analysis suppression is necessary, making future audits and maintenance harder. Agent Prompt
|
||
| // SAFETY: Tests run serially (#[serial]) — no concurrent env mutation. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: These unsafe calls are not made sound merely by serializing the tagged tests: Prompt for AI agents |
||
| unsafe { | ||
| env::set_var(key, value); | ||
| } | ||
| } | ||
|
|
||
| /// Helper to remove env var safely. | ||
| #[allow(unsafe_code)] | ||
| fn remove_env(key: &str) { | ||
| // SAFETY: Tests run serially (#[serial]) — no concurrent env mutation. | ||
| unsafe { | ||
| env::remove_var(key); | ||
| } | ||
| } | ||
|
|
||
| /// Helper to disable auth to avoid JWT secret validation | ||
| fn disable_auth() { | ||
| set_env("MCP__AUTH__ENABLED", "false"); | ||
| } | ||
|
|
||
| /// Helper cleanup for auth | ||
| fn cleanup_auth() { | ||
| remove_env("MCP__AUTH__ENABLED"); | ||
| } | ||
|
|
||
| /// Verify env vars with MCP__ prefix are loaded correctly | ||
| #[test] | ||
| #[serial] | ||
| fn test_mcp_prefix_env_vars_loaded() { | ||
| // Disable auth to avoid JWT validation | ||
| disable_auth(); | ||
| set_env("MCP__PROVIDERS__EMBEDDING__PROVIDER", "test-provider"); | ||
|
|
||
| let config = ConfigLoader::new().load().expect("Should load config"); | ||
|
|
||
| // Verify the provider value was loaded from env | ||
| assert_eq!( | ||
| config.providers.embedding.provider, | ||
| Some("test-provider".to_string()), | ||
| "MCP__ prefixed env vars should be loaded by Figment" | ||
| ); | ||
|
|
||
| remove_env("MCP__PROVIDERS__EMBEDDING__PROVIDER"); | ||
| cleanup_auth(); | ||
| } | ||
|
|
||
| /// Verify old MCB_ prefix is NOT loaded (breaking change per ADR-025) | ||
| #[test] | ||
| #[serial] | ||
| fn test_old_mcb_prefix_not_loaded() { | ||
| // Disable auth to avoid JWT validation | ||
| disable_auth(); | ||
| // Set admin key with OLD prefix (should be ignored) | ||
| set_env("MCB_ADMIN_API_KEY", "old-key-value"); | ||
|
|
||
| let config = ConfigLoader::new().load().expect("Should load config"); | ||
|
|
||
| // Old prefix should NOT be recognized - key should be None | ||
| assert_eq!( | ||
| config.auth.admin.key, None, | ||
| "Old MCB_ prefix should NOT be recognized (ADR-025 breaking change)" | ||
| ); | ||
|
|
||
| remove_env("MCB_ADMIN_API_KEY"); | ||
| cleanup_auth(); | ||
| } | ||
|
|
||
| /// Verify new MCP__ admin key IS loaded correctly | ||
| #[test] | ||
| #[serial] | ||
| fn test_new_admin_key_loaded() { | ||
| // Disable auth to avoid JWT validation | ||
| disable_auth(); | ||
| // Set admin key with NEW prefix | ||
| set_env("MCP__AUTH__ADMIN__KEY", "new-key-value"); | ||
|
|
||
| let config = ConfigLoader::new().load().expect("Should load config"); | ||
|
|
||
| // New prefix should be recognized | ||
| assert_eq!( | ||
| config.auth.admin.key, | ||
| Some("new-key-value".to_string()), | ||
| "MCP__AUTH__ADMIN__KEY should be loaded by Figment" | ||
| ); | ||
|
|
||
| remove_env("MCP__AUTH__ADMIN__KEY"); | ||
| cleanup_auth(); | ||
| } | ||
|
|
||
| /// Verify JWT secret validation fails when empty and auth is enabled | ||
| #[test] | ||
| #[serial] | ||
| fn test_jwt_secret_required_when_auth_enabled() { | ||
| // Enable auth but don't set JWT secret | ||
| set_env("MCP__AUTH__ENABLED", "true"); | ||
| // Deliberately NOT setting MCP__AUTH__JWT__SECRET | ||
|
|
||
| let result = ConfigLoader::new().load(); | ||
|
|
||
| // Should fail validation | ||
| assert!( | ||
| result.is_err(), | ||
| "Config should fail validation when auth.enabled=true but JWT secret is empty" | ||
| ); | ||
|
|
||
| let err = result.unwrap_err().to_string(); | ||
| assert!( | ||
| err.contains("JWT") || err.contains("secret"), | ||
| "Error message should mention JWT secret requirement, got: {}", | ||
| err | ||
| ); | ||
|
|
||
| remove_env("MCP__AUTH__ENABLED"); | ||
| } | ||
|
|
||
| /// Verify watching_enabled config is loaded from Figment, not direct env::var | ||
| #[test] | ||
| #[serial] | ||
| fn test_watching_enabled_via_figment() { | ||
| // Disable auth to avoid JWT validation | ||
| disable_auth(); | ||
| set_env("MCP__SYSTEM__DATA__SYNC__WATCHING_ENABLED", "false"); | ||
|
|
||
| let config = ConfigLoader::new().load().expect("Should load config"); | ||
|
|
||
| // Should be false (default is true) | ||
| assert!( | ||
| !config.system.data.sync.watching_enabled, | ||
| "watching_enabled should be loaded from MCP__SYSTEM__DATA__SYNC__WATCHING_ENABLED" | ||
| ); | ||
|
|
||
| remove_env("MCP__SYSTEM__DATA__SYNC__WATCHING_ENABLED"); | ||
| cleanup_auth(); | ||
| } | ||
|
|
||
| /// Verify that DISABLE_CONFIG_WATCHING env var is NOT supported (legacy removal) | ||
| #[test] | ||
| #[serial] | ||
| fn test_legacy_disable_watching_not_supported() { | ||
| // Disable auth to avoid JWT validation | ||
| disable_auth(); | ||
| // Set OLD env var that should be ignored | ||
| set_env("DISABLE_CONFIG_WATCHING", "true"); | ||
|
|
||
| let config = ConfigLoader::new().load().expect("Should load config"); | ||
|
|
||
| // Old env var should be ignored, watching_enabled should be default (true) | ||
| assert!( | ||
| config.system.data.sync.watching_enabled, | ||
| "DISABLE_CONFIG_WATCHING should NOT affect watching_enabled (use MCP__SYSTEM__DATA__SYNC__WATCHING_ENABLED)" | ||
| ); | ||
|
|
||
| remove_env("DISABLE_CONFIG_WATCHING"); | ||
| cleanup_auth(); | ||
| } | ||
|
|
||
| // ============================================================================ | ||
| // Tests that need clean env state (also serial to avoid interference) | ||
| // ============================================================================ | ||
|
|
||
| /// Verify auth is DISABLED by default (changed from ADR-025 for local development ease) | ||
| /// When auth.enabled=false, JWT secret is not required | ||
| #[test] | ||
| #[serial] | ||
| fn test_auth_disabled_by_default_loads_without_jwt_secret() { | ||
| // Ensure clean state - remove any auth env vars from previous tests | ||
| remove_env("MCP__AUTH__ENABLED"); | ||
| remove_env("MCP__AUTH__JWT__SECRET"); | ||
|
|
||
| // Load config without any env vars set - should SUCCEED because auth is disabled by default | ||
| let result = ConfigLoader::new().load(); | ||
|
|
||
| // Config should load successfully because auth.enabled=false by default | ||
| // No JWT secret is required when auth is disabled | ||
| assert!( | ||
| result.is_ok(), | ||
| "Config should load when auth.enabled=false (default), got error: {:?}", | ||
| result.err() | ||
| ); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2. Disallowed deps in mcb-infrastructure
📘 Rule violation⌂ ArchitectureAgent Prompt
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools