mirror of
https://github.com/syntrex-lab/gomcp.git
synced 2026-04-25 12:26:22 +02:00
- Rename Go module: sentinel-community/gomcp -> syntrex/gomcp (50+ files) - Rename npm package: sentinel-dashboard -> syntrex-dashboard - Update Cargo.toml repository URL to syntrex/syntrex - Update all doc references from DmitrL-dev/AISecurity to syntrex - Add root Makefile (build-all, test-all, lint-all, clean-all) - Add MIT LICENSE - Add .editorconfig (Go/Rust/TS/C cross-language) - Add .github/workflows/ci.yml (Go + Rust + Dashboard) - Add dashboard next.config.ts and .env.example - Clean ARCHITECTURE.md: remove brain/immune/strike/micro-swarm, fix 61->67 engines
110 lines
2.9 KiB
Go
110 lines
2.9 KiB
Go
package contextengine
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
ctxdomain "github.com/syntrex/gomcp/internal/domain/context"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestLoadConfig_FileNotExists(t *testing.T) {
|
|
cfg, err := LoadConfig("/nonexistent/path/context.json")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, ctxdomain.DefaultTokenBudget, cfg.TokenBudget)
|
|
assert.True(t, cfg.Enabled)
|
|
assert.NotEmpty(t, cfg.SkipTools)
|
|
}
|
|
|
|
func TestLoadConfig_ValidFile(t *testing.T) {
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "context.json")
|
|
|
|
content := `{
|
|
"token_budget": 500,
|
|
"max_facts": 15,
|
|
"recency_weight": 0.3,
|
|
"frequency_weight": 0.2,
|
|
"level_weight": 0.25,
|
|
"keyword_weight": 0.25,
|
|
"decay_half_life_hours": 48,
|
|
"enabled": true,
|
|
"skip_tools": ["health", "version"]
|
|
}`
|
|
err := os.WriteFile(path, []byte(content), 0o644)
|
|
require.NoError(t, err)
|
|
|
|
cfg, err := LoadConfig(path)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 500, cfg.TokenBudget)
|
|
assert.Equal(t, 15, cfg.MaxFacts)
|
|
assert.Equal(t, 0.3, cfg.RecencyWeight)
|
|
assert.Equal(t, 48.0, cfg.DecayHalfLifeHours)
|
|
assert.True(t, cfg.Enabled)
|
|
assert.Len(t, cfg.SkipTools, 2)
|
|
assert.True(t, cfg.ShouldSkip("health"))
|
|
assert.True(t, cfg.ShouldSkip("version"))
|
|
assert.False(t, cfg.ShouldSkip("search_facts"))
|
|
}
|
|
|
|
func TestLoadConfig_InvalidJSON(t *testing.T) {
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "context.json")
|
|
|
|
err := os.WriteFile(path, []byte("{invalid json"), 0o644)
|
|
require.NoError(t, err)
|
|
|
|
_, err = LoadConfig(path)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestLoadConfig_InvalidConfig(t *testing.T) {
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "context.json")
|
|
|
|
content := `{"token_budget": 0, "max_facts": 5, "recency_weight": 0.5, "frequency_weight": 0.5, "level_weight": 0, "keyword_weight": 0, "decay_half_life_hours": 24, "enabled": true}`
|
|
err := os.WriteFile(path, []byte(content), 0o644)
|
|
require.NoError(t, err)
|
|
|
|
_, err = LoadConfig(path)
|
|
assert.Error(t, err, "should fail validation: token_budget=0")
|
|
}
|
|
|
|
func TestLoadConfig_OmittedSkipTools_UsesDefaults(t *testing.T) {
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "context.json")
|
|
|
|
content := `{
|
|
"token_budget": 300,
|
|
"max_facts": 10,
|
|
"recency_weight": 0.25,
|
|
"frequency_weight": 0.15,
|
|
"level_weight": 0.30,
|
|
"keyword_weight": 0.30,
|
|
"decay_half_life_hours": 72,
|
|
"enabled": true
|
|
}`
|
|
err := os.WriteFile(path, []byte(content), 0o644)
|
|
require.NoError(t, err)
|
|
|
|
cfg, err := LoadConfig(path)
|
|
require.NoError(t, err)
|
|
assert.NotEmpty(t, cfg.SkipTools, "omitted skip_tools should use defaults")
|
|
assert.True(t, cfg.ShouldSkip("search_facts"))
|
|
}
|
|
|
|
func TestSaveDefaultConfig(t *testing.T) {
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "context.json")
|
|
|
|
err := SaveDefaultConfig(path)
|
|
require.NoError(t, err)
|
|
|
|
// Verify we can load what we saved
|
|
cfg, err := LoadConfig(path)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, ctxdomain.DefaultTokenBudget, cfg.TokenBudget)
|
|
assert.True(t, cfg.Enabled)
|
|
}
|