Skip to content

Commit 03b5f9c

Browse files
author
Yehudit Kerido
committed
[E2E] Add Signal-Decision Engine Test Coverage for New Plugin Architecture
Signed-off-by: Yehudit Kerido <[email protected]>
1 parent ee6e87e commit 03b5f9c

File tree

15 files changed

+1982
-121
lines changed

15 files changed

+1982
-121
lines changed

deploy/kubernetes/aibrix/semantic-router-values/values.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,8 @@ config:
367367
conditions:
368368
- type: "domain"
369369
name: "thinking"
370+
- type: "keyword"
371+
name: "thinking"
370372
modelRefs:
371373
- model: vllm-llama3-8b-instruct
372374
use_reasoning: true
@@ -445,7 +447,7 @@ config:
445447
pii_mapping_path: "models/pii_classifier_modernbert-base_presidio_token_model/pii_type_mapping.json"
446448

447449
keyword_rules:
448-
- category: "thinking"
450+
- name: "thinking"
449451
operator: "OR"
450452
keywords: ["urgent", "immediate", "asap", "think", "careful"]
451453
case_sensitive: false

e2e/README.md

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,13 @@ e2e/
3939
│ ├── domain_classify.go
4040
│ ├── cache.go
4141
│ ├── pii_detection.go
42-
│ └── jailbreak_detection.go
42+
│ ├── jailbreak_detection.go
43+
│ ├── decision_priority.go # Signal-decision: Priority selection
44+
│ ├── plugin_chain_execution.go # Signal-decision: Plugin chains
45+
│ ├── rule_condition_logic.go # Signal-decision: AND/OR operators
46+
│ ├── decision_fallback.go # Signal-decision: Fallback behavior
47+
│ ├── keyword_routing.go # Signal-decision: Keyword matching
48+
│ └── plugin_config_variations.go # Signal-decision: Plugin configs
4349
├── profiles/
4450
│ └── ai-gateway/ # AI Gateway test profile
4551
│ └── profile.go # Profile definition and environment setup
@@ -50,19 +56,48 @@ e2e/
5056

5157
The framework includes the following test cases (all in `e2e/testcases/`):
5258

59+
### Basic Functionality Tests
60+
5361
| Test Case | Description | Metrics |
5462
|-----------|-------------|---------|
5563
| `chat-completions-request` | Basic chat completions API test | Response validation |
5664
| `chat-completions-stress-request` | Sequential stress test with 1000 requests | Success rate, avg duration |
5765
| `chat-completions-progressive-stress` | Progressive QPS stress test (10/20/50/100 QPS) | Per-stage success rate, latency stats |
66+
67+
### Classification and Feature Tests
68+
69+
| Test Case | Description | Metrics |
70+
|-----------|-------------|---------|
5871
| `domain-classify` | Domain classification accuracy | 65 cases, accuracy rate |
5972
| `semantic-cache` | Semantic cache hit rate | 5 groups, cache hit rate |
6073
| `pii-detection` | PII detection and blocking | 10 PII types, detection rate, block rate |
6174
| `jailbreak-detection` | Jailbreak attack detection | 10 attack types, detection rate, block rate |
6275

76+
### Signal-Decision Engine Tests
77+
78+
| Test Case | Description | Metrics |
79+
|-----------|-------------|---------|
80+
| `decision-priority-selection` | Decision priority selection with multiple matches | 4 cases, priority validation |
81+
| `plugin-chain-execution` | Plugin execution order (PII → Cache → System Prompt) | 4 cases, chain validation, blocking behavior |
82+
| `rule-condition-logic` | AND/OR operators and keyword matching | 6 cases, operator validation |
83+
| `decision-fallback-behavior` | Fallback to default decision when no match | 5 cases, fallback validation |
84+
| `keyword-routing` | Keyword-based routing decisions | 6 cases, keyword matching (case-insensitive) |
85+
| `plugin-config-variations` | Plugin configuration variations (PII allowlist, cache thresholds) | 6 cases, config validation |
86+
87+
**Signal-Decision Engine Features Tested:**
88+
89+
- ✅ Decision priority selection (priority 15 > 10)
90+
- ✅ Plugin chain execution order and blocking
91+
- ✅ Rule condition logic (AND/OR operators)
92+
- ✅ Keyword-based routing (case-insensitive)
93+
- ✅ Decision fallback behavior
94+
- ✅ Per-decision plugin configurations
95+
- ✅ PII allowlist handling
96+
- ✅ Per-decision cache thresholds (0.75, 0.92, 0.95)
97+
6398
All test cases:
6499

65-
- Use model name `"MoM"`
100+
- Use model name `"MoM"` to trigger decision engine
66101
- Automatically clean up port forwarding
67102
- Generate detailed reports with statistics
68103
- Support verbose logging
@@ -312,6 +347,15 @@ Test data is stored in `e2e/testcases/testdata/` as JSON files. Each test case l
312347
- `pii_detection_cases.json`: 10 PII types (email, phone, SSN, etc.)
313348
- `jailbreak_detection_cases.json`: 10 attack types (prompt injection, DAN, etc.)
314349

350+
**Signal-Decision Engine Tests** use embedded test cases (defined inline in test files) to validate:
351+
352+
- Decision priority mechanisms (4 test cases)
353+
- Plugin chain execution and blocking (4 test cases)
354+
- Rule condition logic with AND/OR operators (6 test cases)
355+
- Decision fallback behavior (5 test cases)
356+
- Keyword-based routing (6 test cases)
357+
- Plugin configuration variations (6 test cases)
358+
315359
**Test Data Format Example:**
316360

317361
```json

e2e/profiles/ai-gateway/profile.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,27 @@ func (p *Profile) Teardown(ctx context.Context, opts *framework.TeardownOptions)
107107
// GetTestCases returns the list of test cases for this profile
108108
func (p *Profile) GetTestCases() []string {
109109
return []string{
110+
// Basic functionality tests
110111
"chat-completions-request",
111112
"chat-completions-stress-request",
113+
114+
// Classification and routing tests
112115
"domain-classify",
116+
117+
// Feature tests
113118
"semantic-cache",
114119
"pii-detection",
115120
"jailbreak-detection",
121+
122+
// Signal-Decision engine tests (new architecture)
123+
"decision-priority-selection", // Priority-based routing
124+
"plugin-chain-execution", // Plugin ordering and blocking
125+
"rule-condition-logic", // AND/OR operators
126+
"decision-fallback-behavior", // Fallback to default
127+
"keyword-routing", // Keyword-based decisions
128+
"plugin-config-variations", // Plugin configuration testing
129+
130+
// Load tests
116131
"chat-completions-progressive-stress",
117132
}
118133
}

e2e/profiles/ai-gateway/values.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ config:
367367
operator: "OR"
368368
conditions:
369369
- type: "keyword"
370-
rule_name: "thinking"
370+
name: "thinking"
371371
modelRefs:
372372
- model: base-model
373373
lora_name: general-expert
@@ -383,7 +383,7 @@ config:
383383
system_prompt: "You are a thinking expert, should think multiple steps before answering. Please answer the question step by step."
384384
mode: "replace"
385385

386-
- name: general_decision
386+
- name: other_decision
387387
description: "General knowledge and miscellaneous topics"
388388
priority: 1
389389
rules:
@@ -474,7 +474,7 @@ config:
474474
pii_mapping_path: "models/pii_classifier_modernbert-base_presidio_token_model/pii_type_mapping.json"
475475

476476
keyword_rules:
477-
- category: "thinking"
477+
- name: "thinking"
478478
operator: "OR"
479479
keywords: ["urgent", "immediate", "asap", "think", "careful"]
480480
case_sensitive: false

e2e/profiles/aibrix/profile.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,27 @@ func (p *Profile) Teardown(ctx context.Context, opts *framework.TeardownOptions)
167167
// GetTestCases returns the list of test cases for this profile
168168
func (p *Profile) GetTestCases() []string {
169169
return []string{
170+
// Basic functionality tests
170171
"chat-completions-request",
171172
"chat-completions-stress-request",
173+
174+
// Classification and routing tests
172175
"domain-classify",
176+
177+
// Feature tests
173178
"semantic-cache",
174179
"pii-detection",
175180
"jailbreak-detection",
181+
182+
// Signal-Decision engine tests (new architecture)
183+
"decision-priority-selection", // Priority-based routing
184+
"plugin-chain-execution", // Plugin ordering and blocking
185+
"rule-condition-logic", // AND/OR operators
186+
"decision-fallback-behavior", // Fallback to default
187+
"keyword-routing", // Keyword-based decisions
188+
"plugin-config-variations", // Plugin configuration testing
189+
190+
// Load tests
176191
"chat-completions-progressive-stress",
177192
}
178193
}

e2e/profiles/dynamic-config/crds/intelligentroute.yaml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,43 @@ spec:
3232
description: "Philosophy and ethical questions"
3333
- name: "engineering"
3434
description: "Engineering and technical problem-solving"
35+
- name: "thinking"
36+
description: "Queries requiring careful thought or urgent attention"
3537
- name: "other"
3638
description: "General knowledge and miscellaneous topics"
3739

40+
keywords:
41+
- name: "thinking"
42+
operator: "OR"
43+
keywords: ["urgent", "immediate", "asap", "think", "careful"]
44+
case_sensitive: false
45+
3846
decisions:
47+
- name: "thinking_decision"
48+
priority: 15
49+
description: "Queries requiring careful thought or urgent attention"
50+
signals:
51+
operator: "OR"
52+
conditions:
53+
- type: "domain"
54+
name: "thinking"
55+
- type: "keyword"
56+
name: "thinking"
57+
modelRefs:
58+
- model: "base-model"
59+
loraName: "math-expert"
60+
useReasoning: true
61+
plugins:
62+
- type: "pii"
63+
configuration:
64+
enabled: true
65+
pii_types_allowed: []
66+
- type: "system_prompt"
67+
configuration:
68+
enabled: true
69+
system_prompt: "You are a thoughtful assistant trained to approach problems systematically. When handling urgent matters or complex questions, break down the problem into clear steps, consider multiple angles, and provide thorough, well-reasoned responses. Take your time to think through implications and edge cases."
70+
mode: "replace"
71+
3972
- name: "business_decision"
4073
priority: 10
4174
description: "Business and management related queries"
@@ -328,6 +361,27 @@ spec:
328361
conditions:
329362
- type: "domain"
330363
name: "engineering"
364+
modelRefs:
365+
- model: "base-model"
366+
loraName: "science-expert"
367+
useReasoning: false
368+
plugins:
369+
- type: "pii"
370+
configuration:
371+
enabled: true
372+
pii_types_allowed: []
373+
- type: "system_prompt"
374+
configuration:
375+
enabled: true
376+
system_prompt: "You are an engineering expert with knowledge across multiple engineering disciplines including mechanical, electrical, civil, chemical, software, and systems engineering. Apply engineering principles, design methodologies, and problem-solving approaches to provide practical solutions. Consider safety, efficiency, sustainability, and cost-effectiveness in your recommendations. Use technical precision while explaining concepts clearly, and emphasize the importance of proper engineering practices and standards."
377+
mode: "replace"
378+
379+
- name: "other_decision"
380+
priority: 1
381+
description: "General knowledge and miscellaneous topics"
382+
signals:
383+
operator: "OR"
384+
conditions:
331385
- type: "domain"
332386
name: "other"
333387
modelRefs:
@@ -339,6 +393,10 @@ spec:
339393
configuration:
340394
enabled: true
341395
pii_types_allowed: []
396+
- type: "semantic-cache"
397+
configuration:
398+
enabled: true
399+
similarity_threshold: 0.75
342400
- type: "system_prompt"
343401
configuration:
344402
enabled: true

e2e/profiles/dynamic-config/profile.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,27 @@ func (p *Profile) Teardown(ctx context.Context, opts *framework.TeardownOptions)
104104
// GetTestCases returns the list of test cases for this profile
105105
func (p *Profile) GetTestCases() []string {
106106
return []string{
107+
// Basic functionality tests
107108
"chat-completions-request",
108109
"chat-completions-stress-request",
110+
111+
// Classification and routing tests
109112
"domain-classify",
113+
114+
// Feature tests
110115
"semantic-cache",
111116
"pii-detection",
112117
"jailbreak-detection",
118+
119+
// Signal-Decision engine tests (new architecture)
120+
"decision-priority-selection", // Priority-based routing
121+
"plugin-chain-execution", // Plugin ordering and blocking
122+
"rule-condition-logic", // AND/OR operators
123+
"decision-fallback-behavior", // Fallback to default
124+
"keyword-routing", // Keyword-based decisions
125+
"plugin-config-variations", // Plugin configuration testing
126+
127+
// Load tests
113128
"chat-completions-progressive-stress",
114129
}
115130
}

e2e/testcases/common.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,11 @@ func formatResponseHeaders(headers map[string][]string) string {
144144
}
145145
return sb.String()
146146
}
147+
148+
// truncateString truncates a string to maxLen characters, adding "..." if truncated
149+
func truncateString(s string, maxLen int) string {
150+
if len(s) <= maxLen {
151+
return s
152+
}
153+
return s[:maxLen-3] + "..."
154+
}

0 commit comments

Comments
 (0)