Component-Aware Test Gap Analysis Skill
This skill automatically detects component type (networking, storage, API, etc.) and provides context-aware gap analysis. It analyzes e2e test files to identify missing test coverage specific to the component being tested.
When to Use This Skill
Use this skill when you need to:
- Automatically detect component type from test file path and content
- Component-specific gap analysis:
- Networking: Identify missing protocol tests (TCP, UDP, SCTP), service type coverage, IP stack testing
- Storage: Find gaps in storage class coverage, volume mode testing, provisioner tests
- Generic: Analyze platform coverage and common scenarios for other components
- Always analyze: Cloud platform coverage (AWS, Azure, GCP, etc.) and scenario testing (error handling, upgrades, RBAC, scale)
- Prioritize testing efforts based on component-specific production importance
- Generate comprehensive component-aware gap analysis reports
⚠️ CRITICAL REQUIREMENT
This skill MUST ALWAYS generate all three report formats (HTML, JSON, and Text) at runtime.
The gap analyzer script (generated at runtime to .work/test-coverage/gaps/gap_analyzer.py) performs the analysis and returns structured data. Claude Code is responsible for generating all three report formats based on this data.
Required Actions:
- ✅ Execute:
python3 .work/test-coverage/gaps/gap_analyzer.py <test-file> --output-json (outputs structured JSON to stdout)
- ✅ Generate: Create all three report files (HTML, JSON, Text) at runtime
- ✅ Verify: All three reports are generated successfully
- ✅ Display: Show report locations and summary to the user
Failure to generate any of the three report formats should be treated as a skill execution failure.
Prerequisites
Required Tools
- Python 3.8+ for test structure analysis
- Go toolchain for the target project
Installation
# Python dependencies (standard library only, no external packages required)
# Ensure Python 3.8+ is installed
# Optional Go analysis tools
go install golang.org/x/tools/cmd/guru@latest
go install golang.org/x/tools/cmd/goimports@latest
How It Works
Note: This skill currently supports E2E/integration test files for OpenShift/Kubernetes components written in Go (Ginkgo framework).
Current Implementation
The analyzer performs single test file analysis with two analysis layers:
Generic Coverage Analysis (keyword-based)
- Platforms, protocols, IP stacks, service types
- Uses regex pattern matching on file content
Feature-Based Analysis (runtime extraction)
- Dynamically extracts features from test names
- Infers missing features based on patterns
- No hardcoded feature matrices - works for ANY component
It does not perform repository traversal, Go AST parsing, or test-to-source mapping.
Analysis Flow
Step 1: Component Type Detection
The analyzer automatically detects the component type from:
File path patterns:
/networking/ → networking component
/storage/ → storage component
/kapi/, /api/ → kube-api component
/etcd/ → etcd component
/auth/, /rbac/ → auth component
File content patterns:
- Keywords like
sig-networking, networkpolicy, egressip → networking
- Keywords like
sig-storage, persistentvolume → storage
- Keywords like
sig-api, apiserver → kube-api
Step 2: Extract Test Cases
Parses the test file using regex to extract:
- Test names from Ginkgo
g.It("test name") patterns
- Line numbers where tests are defined
- Test tags like
[Serial], [Disruptive], [NonPreRelease]
- Test IDs from patterns like
-12345- in test names
Example:
g.It("egressip-12345-should work on AWS [Serial]", func() {
// Test implementation
})
Extracted:
- Name:
egressip-12345-should work on AWS [Serial]
- ID:
12345
- Tags:
[Serial]
- Line: 42
Step 3: Analyze Coverage Using Regex
For each component type, the analyzer searches the file content for specific keywords to determine what is tested:
Networking components:
- Platforms:
vsphere, AWS, azure, GCP, baremetal
- Protocols:
TCP, UDP, SCTP
- Service types:
NodePort, LoadBalancer, ClusterIP
- Scenarios:
invalid, upgrade, concurrent, performance, rbac
Storage components:
- Platforms:
vsphere, AWS, azure, GCP, baremetal
- Storage classes:
gp2, gp3, csi
- Volume modes:
ReadWriteOnce, ReadWriteMany, ReadOnlyMany
- Scenarios:
invalid, upgrade, concurrent, performance, rbac
Other components:
- Platforms:
vsphere, AWS, azure, GCP, baremetal
- Scenarios:
invalid, upgrade, concurrent, performance, rbac
Step 4: Identify Gaps
For each coverage dimension, if a keyword is not found in the file, it's flagged as a gap:
Example:
# If file content doesn't contain "azure" (case-insensitive)
gaps.append({
'platform': 'Azure',
'priority': 'high',
'impact': 'Major cloud provider - production blocker',
'recommendation': 'Add Azure platform-specific tests'
})
Step 5: Calculate Component-Aware Coverage Scores
Scoring is component-specific to avoid penalizing components for irrelevant metrics:
Networking components:
- Overall = avg(platform_score, protocol_score, service_type_score, scenario_score)
Storage components:
- Overall = avg(platform_score, storage_class_score, volume_mode_score, scenario_score)
Other components:
- Overall = avg(platform_score, scenario_score)
Each dimension score = (items_found / total_items) × 100
Step 5a: Dynamic Feature Extraction (Runtime Analysis)
In addition to the keyword-based coverage analysis above, the analyzer performs dynamic feature extraction to identify component-specific features from test names at runtime, without any hardcoded feature matrices.
How Runtime Feature Extraction Works:
Extract Features from Test Names
Parse test names to identify features being tested:
Example Test Name:
"Validate egressIP with mixed of multiple non-overlapping UDNs and default network(layer3/2 and IPv4 only)"
Extracted Features:
- ✓ Non-overlapping configuration
- ✓ Multiple resource configuration
- ✓ Mixed configuration
- ✓ User Defined Networks (UDN)
- ✓ Default network
- ✓ Layer 3 networking
Group Features into Categories
Features are automatically categorized:
- Configuration Patterns: overlapping, non-overlapping, single, multiple, mixed
- Network Topology: UDN, default network, layer2, layer3, gateway modes
- Lifecycle Operations: creation, deletion, recreation, assignment
- Network Features: failover, load balancing, isolation
- Resilience & Recovery: reboot, restart, node deletion
Infer Missing Features
Based on patterns, infer what's missing:
- Opposite patterns: If "overlapping" tested → suggest "non-overlapping"
- Single vs Multiple: If "single resource" tested → suggest "multiple resources"
- Completeness: If "deletion" tested → suggest "recreation"
- Layer coverage: If "layer2" tested → suggest "layer3"
Benefits of Runtime Feature Extraction:
✅ No Hardcoding - Works for ANY component without configuration
✅ Intelligent Gap Detection - Infers missing features based on patterns
✅ Component-Agnostic - Automatically adapts to any component type
✅ Always Current - Extracts from actual test names, not assumed features
Example: EgressIP Test Analysis
Input (Test Names):
1. Validate egressIP with mixed of multiple non-overlapping UDNs
2. Validate egressIP with mixed of multiple overlapping UDNs
3. Validate egressIP Failover with UDNs
4. egressIP after UDN deleted then recreated
5. egressIP after OVNK restarted
6. Traffic is load balanced between egress nodes
Output (Extracted Features):
Configuration Patterns:
✓ Non-overlapping configuration
✓ Overlapping configuration
✓ Multiple resource configuration
✓ Mixed configuration
Network Topology:
✓ User Defined Networks (UDN)
Lifecycle Operations:
✓ Resource deletion
✓ Resource recreation
Network Features:
✓ Failover
✓ Load balancing
Resilience & Recovery:
✓ OVN-Kubernetes restart
Output (Inferred Feature Gaps):
[HIGH] Single resource configuration
- Pattern suggests "multiple" tested but not "single"
- Recommendation: Add single resource baseline tests
[HIGH] Layer 2 networking
- Layer 3 tested but Layer 2 missing
- Recommendation: Add Layer 2 network topology tests
[MEDIUM] Local gateway mode
- Gateway mode mentioned but local vs shared not clear
- Recommendation: Add explicit gateway mode tests
Integration in gap_analyzer.py:
The dynamic feature extractor is built into the analyzer (no separate import needed):
# After extracting test cases
feature_analysis = extract_features_from_tests(test_cases)
# Results included in analysis output
tested_features = feature_analysis['tested_features']
# {'Configuration Patterns': ['Overlapping', 'Non-overlapping', ...],
# 'Network Topology': ['UDN', 'Layer3', ...]}
feature_gaps = feature_analysis['feature_gaps']
# [{'feature': 'Multiple resources', 'priority': 'high', ...}]
coverage_stats = feature_analysis['coverage_stats']
# {'features_tested': 14, 'features_missing': 5}
Report Integration:
Feature analysis is included in all three report formats:
- HTML Reports: Feature sections with tested/missing features
- Text Reports: Feature lists grouped by category
- JSON Reports: Structured feature data for CI/CD integration
Limitations
The current implementation has the following limitations:
❌ No repository traversal - Analyzes only the single test file provided as input
❌ No Go AST parsing - Uses regex pattern matching instead of parsing Go syntax trees
❌ No test-to-source mapping - Cannot map test functions to source code functions
❌ No function-level coverage - Cannot determine which source functions are tested
❌ No project-wide analysis - Cannot analyze multiple test files or aggregate results
❌ Keyword-based detection only - Gap detection relies on keyword presence in test file
❌ Single file focus - Reports cover only the analyzed test file, not the entire codebase
These limitations mean the analyzer provides scenario and platform coverage analysis for a single E2E test file, not structural code coverage across a codebase.
Step 6: Generate Reports
The analyzer generates three report formats. You should generate Python code at runtime to create these reports.
1. HTML Gap Report (test-gaps-report.html)
Purpose: Interactive, filterable HTML report for visual gap analysis with professional styling
HTML Document Structure:
Generate a complete HTML5 document with the following structure:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test Coverage Gap Analysis - {filename}</title>
<style>
/* Inline all CSS styles here - see CSS Styles section below */
</style>
</head>
<body>
<div class="container">
<!-- Content sections -->
</div>
<script>
/* JavaScript for gap filtering - see JavaScript section below */
</script>
</body>
</html>
CSS Styles (Inline in <style> tag):
Generate comprehensive CSS with the following style rules:
Reset and Base Styles:
*: box-sizing: border-box, margin: 0, padding: 0
body: font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; background: #f5f5f5; padding: 20px
Container and Layout:
.container: max-width: 1400px, margin: 0 auto, background: white, padding: 30px, border-radius: 8px, box-shadow: 0 2px 10px rgba(0,0,0,0.1)
h1: color: #2c3e50, margin-bottom: 10px, font-size: 2em
h2: color: #34495e, margin-top: 30px, margin-bottom: 15px, padding-bottom: 10px, border-bottom: 2px solid #e74c3c, font-size: 1.5em
h3: color: #34495e, margin-top: 20px, margin-bottom: 10px, font-size: 1.2em
Metadata Section:
.metadata: background: #ecf0f1, padding: 15px, border-radius: 5px, margin-bottom: 25px
.metadata p: margin: 5px 0
Score Cards:
.score-grid: display: grid, grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)), gap: 15px, margin: 20px 0
.score-card: padding: 20px, border-radius: 8px, text-align: center, color: white
.score-card.excellent: background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%) (score >= 80)
.score-card.good: background: linear-gradient(135deg, #3498db 0%, #2980b9 100%) (score >= 60)
.score-card.fair: background: linear-gradient(135deg, #f39c12 0%, #e67e22 100%) (score >= 40)
.score-card.poor: background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%) (score < 40)
.score-card .number: font-size: 2.5em, font-weight: bold, margin: 10px 0
.score-card .label: font-size: 0.9em, opacity: 0.9
Gap Cards:
.gap-card: background: #fff, border-left: 4px solid #e74c3c, padding: 20px, margin: 15px 0, border-radius: 5px, box-shadow: 0 2px 5px rgba(0,0,0,0.1)
.gap-card.high: border-left-color: #e74c3c
.gap-card.medium: border-left-color: #f39c12
.gap-card.low: border-left-color: #3498db
.gap-card h4: color: #2c3e50, margin-bottom: 10px, font-size: 1.1em
.gap-card .gap-id: font-family: "Courier New", monospace, font-size: 0.85em, color: #7f8c8d, margin-bottom: 5px
.priority: display: inline-block, padding: 4px 12px, border-radius: 12px, font-size: 0.75em, font-weight: bold, margin-right: 8px
.priority.high: background: #e74c3c, color: white
.priority.medium: background: #f39c12, color: white
.priority.low: background: #3498db, color: white
.gap-card .impact: background: #fff3cd, border-left: 3px solid #ffc107, padding: 10px, margin: 10px 0, border-radius: 3px
.gap-card .recommendation: background: #d4edda, border-left: 3px solid #28a745, padding: 10px, margin: 10px 0, border-radius: 3px
Tables:
table: width: 100%, border-collapse: collapse, margin: 20px 0
th, td: padding: 12px, text-align: left, border-bottom: 1px solid #ddd
th: background: #34495e, color: white, font-weight: 600
tr:hover: background: #f5f5f5
.tested: background: #d4edda, color: #155724, font-weight: bold, text-align: center
.not-tested: background: #f8d7da, color: #721c24, font-weight: bold, text-align: center
Summary Boxes:
.summary-box: background: #e3f2fd, border-left: 4px solid #2196f3, padding: 15px, margin: 20px 0, border-radius: 5px
.warning-box: background: #fff3cd, border-left: 4px solid #ffc107, padding: 15px, margin: 20px 0, border-radius: 5px
.success-box: background: #d4edda, border-left: 4px solid #28a745, padding: 15px, margin: 20px 0, border-radius: 5px
Filter Buttons:
.filter-buttons: margin: 20px 0
.filter-btn: padding: 10px 20px, margin-right: 10px, border: none, border-radius: 5px, cursor: pointer, font-weight: bold
.filter-btn.active: box-shadow: 0 0 0 3px rgba(0,0,0,0.2)
.filter-btn.all: background: #95a5a6, color: white
.filter-btn.high: background: #e74c3c, color: white
.filter-btn.medium: background: #f39c12, color: white
.filter-btn.low: background: #3498db, color: white
HTML Content Sections:
Metadata Section:
<div class="metadata">
<p><strong>File:</strong> <code>{escaped_filename}</code></p>
<p><strong>Path:</strong> <code>{escaped_filepath}</code></p>
<p><strong>Component:</strong> {escaped_component_title}</p>
<p><strong>Analysis Date:</strong> {YYYY-MM-DD}</p>
<p><strong>Total Test Cases:</strong> {count}</p>
</div>
Coverage Scores Section:
- Display score cards in a grid
- Show scores dynamically based on what's calculated for the component
- Score display order and labels:
SCORE_DISPLAY = {
'overall': {'order': 1, 'label': 'Overall Coverage'},
'platform_coverage': {'order': 2, 'label': 'Platform Coverage'},
'ip_stack_coverage': {'order': 3, 'label': 'IP Stack Coverage'},
'topology_coverage': {'order': 4, 'label': 'Topology Coverage'},
'network_layer_coverage': {'order': 5, 'label': 'Network Layer Coverage'},
'gateway_mode_coverage': {'order': 6, 'label': 'Gateway Mode Coverage'},
'protocol_coverage': {'order': 5, 'label': 'Protocol Coverage'},
'service_type_coverage': {'order': 6, 'label': 'Service Type Coverage'},
'storage_class_coverage': {'order': 7, 'label': 'Storage Class Coverage'},
'volume_mode_coverage': {'order': 8, 'label': 'Volume Mode Coverage'},
'scenario_coverage': {'order': 99, 'label': 'Scenario Coverage'},
}
- Sort scores by order, render only non-zero/non-None scores
- Apply CSS class based on score value:
get_score_class(score)
- If overall < 60%, add a warning box with key findings
What's Tested Section:
Coverage Gaps Section:
Recommendations Section:
- Success box with top 5 high-priority gaps listed
- Bulleted list of immediate actions
JavaScript for Filtering (Inline in <script> tag):
function filterGaps(priority) {
const cards = document.querySelectorAll('.gap-card');
const buttons = document.querySelectorAll('.filter-btn');
buttons.forEach(btn => btn.classList.remove('active'));
document.querySelector(`.filter-btn.${priority}`).classList.add('active');
cards.forEach(card => {
if (priority === 'all' || card.dataset.priority === priority) {
card.style.display = 'block';
} else {
card.style.display = 'none';
}
});
}
Security Requirements:
- Use
html.escape() for all user-provided content (filenames, test names, gap descriptions)
- Sanitize priority values to only allow: 'high', 'medium', 'low'
- Never inject raw HTML from analysis data
Helper Functions to Implement:
get_score_class(score):
- score >= 80: return 'excellent'
- score >= 60: return 'good'
- score >= 40: return 'fair'
- else: return 'poor'
Escape all strings using from html import escape
Component-Specific Behavior:
Networking components (networking, router, dns, network-observability):
- Show: platforms, protocols, service types, IP stacks, topologies, network layers, gateway modes, scenarios
Storage components (storage, csi):
- Show: platforms, storage classes, volume modes, volumes, CSI drivers, snapshots, scenarios
Other components:
- Show: platforms, scenarios only
2. JSON Report (test-gaps-report.json)
Generated by: Claude Code at runtime based on analyzer output
Purpose: Machine-readable format for CI/CD integration
Structure:
{
"analysis": {
"file": "path/to/test/file.go",
"component_type": "networking",
"test_count": 15,
"test_cases": [
{
"name": "test name",
"line": 42,
"id": "12345",
"tags": ["Serial", "Disruptive"]
}
],
"coverage": {
"platforms": {
"tested": ["AWS", "GCP"],
"not_tested": ["Azure", "vSphere", "Bare Metal"]
},
"protocols": {
"tested": ["TCP"],
"not_tested": ["UDP", "SCTP"]
}
},
"gaps": {
"platforms": [
{
"platform": "Azure",
"priority": "high",
"impact": "Major cloud provider",
"recommendation": "Add Azure tests"
}
],
"protocols": [],
"scenarios": []
}
},
"scores": {
"overall": 45.0,
"platform_coverage": 33.3,
"protocol_coverage": 33.3,
"scenario_coverage": 40.0
},
"generated_at": "2025-11-10T10:00:00Z"
}
Implementation: Use json.dump() with indent=2 for readable output
3. Text Summary (test-gaps-summary.txt)
Generated by: Claude Code at runtime based on analyzer output
Purpose: Terminal-friendly summary for quick review
Format Structure:
============================================================
Test Coverage Gap Analysis
============================================================
File: {filename}
Component: {component_type}
Test Cases: {count}
Analysis Date: {timestamp}
============================================================
Coverage Scores
============================================================
Overall Coverage: {score}%
Platform Coverage: {score}%
[Component-specific scores based on type]
Scenario Coverage: {score}%
============================================================
What's Tested
============================================================
Platforms:
✓ {platform1}
✓ {platform2}
[Additional tested items based on component type]
============================================================
Identified Gaps
============================================================
PLATFORM GAPS:
[PRIORITY] {platform}
Impact: {impact}
Recommendation: {recommendation}
[Additional gap sections based on component type]
============================================================
Recommendations
============================================================
Current Coverage: {current}%
Target Coverage: {target}%
Focus on addressing HIGH priority gaps first to maximize
test coverage and ensure production readiness.
Component-Specific Sections:
- Networking components: Include protocol, service type, IP stack, topology gaps
- Storage components: Include storage class, volume mode gaps
- Other components: Only include platform and scenario gaps
Implementation: Use '\n'.join(lines) to build the text content
Implementation Steps
When implementing this skill in a command:
Step 0: Generate Analyzer Script at Runtime
CRITICAL: Before running any analysis, generate the analyzer script from the reference implementation.
# Create output directory
mkdir -p .work/test-coverage/gaps/
# Generate the analyzer script from the specification below
# Claude Code will write gap_analyzer.py based on the Analyzer Specification section
Analyzer Specification:
Generate a Python script (gap_analyzer.py) that performs component-aware E2E test gap analysis:
Input: Path or URL to a Go test file (Ginkgo framework)
Output: JSON to stdout with analysis results and coverage scores
Core Algorithm:
Input Processing (handle URLs and local paths):
- Check if input starts with
http:// or https://
- If URL: Use
urllib.request.urlopen() to fetch content, save to temp file
- If local path: Use directly
- After analysis: Clean up temp file if created
Component Detection (auto-detect from file path/content):
- Networking:
/networking/, egressip, networkpolicy → component_type='networking'
- Storage:
/storage/, persistentvolume → component_type='storage'
- Other components: etcd, apiserver, mco, operators, etc.
Test Extraction (regex-based):
- Pattern:
(?:g\.|o\.)?It\(\s*["']([^"']+)["']
- Extract: test name, line number, tags ([Serial], [Disruptive]), test ID (pattern:
-\d+-)
Coverage Analysis (keyword search in file content):
- Platforms: Search for
aws|azure|gcp|vsphere|baremetal|rosa (case-insensitive)
- Protocols: Search for
\bTCP\b, \bUDP\b, \bSCTP\b, curl|wget|http (TCP via HTTP)
- IP Stacks: Search for
ipv4, ipv6, dualstack
- Service Types: Search for
NodePort, LoadBalancer, ClusterIP
- Network Layers (networking only):
layer2|l2, layer3|l3, default network
- Gateway Modes (networking only):
- Search for
local.gateway|lgw → if found, Local Gateway is tested
- Shared Gateway is DEFAULT in OVN-K: if tests exist but no local gateway pattern found → Shared Gateway is tested
- If no tests exist → neither is tested
- Topologies:
sno|single-node, multi-node|HA cluster, hypershift|hcp, check NonHyperShiftHOST tag
- Scenarios:
failover, reboot, restart, delete, invalid, upgrade, concurrent, performance, rbac, traffic disruption
Gap Identification:
- For each category, items NOT found = gaps
- Assign priority: high (production-critical), medium (important), low (nice-to-have)
- Platform gaps: Azure/GCP/AWS = high, vSphere/Bare Metal = medium
- Protocol gaps: UDP = high, SCTP = medium, TCP non-HTTP = low
- Service type gaps: LoadBalancer = high, others = medium
- Scenario gaps: Error Handling = high, Traffic Disruption = high (networking only)
Coverage Scoring (component-aware):
- Networking: avg(platform, protocol, service_type, ip_stack, network_layer, gateway_mode, topology, scenario)
- Storage: avg(platform, storage_class, volume_mode, scenario)
- Other: avg(platform, scenario)
- Each dimension: (tested_count / total_count) × 100
Output Format (JSON to stdout):
{
"analysis": {
"file": "/path/to/test.go",
"component_type": "networking",
"test_count": 15,
"test_cases": [...],
"coverage": {
"platforms": {"tested": [...], "not_tested": [...]},
"protocols": {"tested": [...], "not_tested": [...]},
...
},
"gaps": {
"platforms": [{"platform": "Azure", "priority": "high", "impact": "...", "recommendation": "..."}],
...
}
},
"scores": {
"overall": 62.0,
"platform_coverage": 100.0,
...
}
}
Why Runtime Generation:
- Claude Code generates the analyzer from this specification
- No separate
.py file to maintain
- SKILL.md is the single source of truth
- Claude Code is excellent at generating code from specifications
Step 1: Execute Gap Analyzer Script (MANDATORY)
Execute the gap analyzer script to perform analysis and return structured data:
# Run gap analyzer (outputs structured JSON to stdout)
python3 .work/test-coverage/gaps/gap_analyzer.py <test-file-path> --output-json
The analyzer will output structured JSON to stdout containing:
- Component type detection
- Test case extraction
- Coverage analysis
- Gap identification
- Priority scoring
- Component-specific recommendations
IMPORTANT: Do not skip this step. Do not attempt manual analysis. The script is the authoritative implementation.
Step 2: Capture and Parse Analyzer Output
import json
import subprocess
# Run analyzer and capture JSON output
result = subprocess.run(
['python3', '.work/test-coverage/gaps/gap_analyzer.py', test_file, '--output-json'],
capture_output=True,
text=True
)
# Parse structured data
analysis_data = json.loads(result.stdout)
Step 3: Generate All Three Report Formats at Runtime (MANDATORY)
IMPORTANT: Claude Code generates all three report formats based on the analyzer's structured output.
3.1: Generate JSON Report
json_path = '.work/test-coverage/gaps/test-gaps-report.json'
with open(json_path, 'w') as f:
json.dump(analysis_data, f, indent=2)
3.2: Generate Text Summary Report
Follow the text format specification in Step 6 to generate a terminal-friendly summary.
text_path = '.work/test-coverage/gaps/test-gaps-summary.txt'
# Generate text content following format in Step 6
with open(text_path, 'w') as f:
f.write(text_content)
3.3: Generate HTML Report
Follow the HTML specification in Step 6 to generate an interactive report.
html_path = '.work/test-coverage/gaps/test-gaps-report.html'
# Generate HTML content following specification in Step 6
# Include all CSS styles, JavaScript filtering, and component-specific sections
with open(html_path, 'w') as f:
f.write(html_content)
Key Requirements:
- Generate HTML following the exact structure in "Step 6: Generate Reports" above
- Include all CSS styles inline in
<style> tag
- Include JavaScript filtering function in
<script> tag
- Escape all user-provided content with
html.escape()
- Apply component-specific sections based on component type
Step 4: Display Results
After generating all three reports, display the results to the user:
# Display summary (from text report or analysis_data)
print(f"Component detected: {analysis_data['analysis']['component_type']}")
print(f"Overall coverage: {analysis_data['scores']['overall']}%")
print(f"High-priority gaps: {high_priority_count}")
# Provide report locations
print("\nReports Generated:")
print(" ✓ HTML: .work/test-coverage/gaps/test-gaps-report.html")
print(" ✓ JSON: .work/test-coverage/gaps/test-gaps-report.json")
print(" ✓ Text: .work/test-coverage/gaps/test-gaps-summary.txt")
Step 5: Parse Analysis Data (Optional)
For programmatic access to gap data, use the analysis_data from Step 2:
# Access analysis results (from analysis_data captured in Step 2)
component_type = analysis_data['analysis']['component_type']
test_count = analysis_data['analysis']['test_count']
overall_score = analysis_data['scores']['overall']
# Access gaps
platform_gaps = analysis_data['analysis']['gaps']['platforms']
protocol_gaps = analysis_data['analysis']['gaps'].get('protocols', [])
scenario_gaps = analysis_data['analysis']['gaps']['scenarios']
# Filter high-priority gaps
high_priority_gaps = [
gap for category in analysis_data['analysis']['gaps'].values()
for gap in category if gap.get('priority') == 'high'
]
⚠️ MANDATORY PRE-COMPLETION VALIDATION
CRITICAL: Before declaring this skill complete, you MUST execute ALL validation checks below. Failure to validate is considered incomplete execution.
Validation Checklist
Execute these verification steps in order. ALL must pass:
1. File Existence Check
# Verify all three reports exist
test -f .work/test-coverage/gaps/test-gaps-report.html && echo "✓ HTML exists" || echo "✗ HTML MISSING"
test -f .work/test-coverage/gaps/test-gaps-report.json && echo "✓ JSON exists" || echo "✗ JSON MISSING"
test -f .work/test-coverage/gaps/test-gaps-summary.txt && echo "✓ Text exists" || echo "✗ Text MISSING"
Required: All three files must exist. If any are missing, regenerate them.
2. Dynamic Feature Extraction Verification
# Verify HTML has "Tested Features (Dynamic Feature Extraction)" section
grep -q "Tested Features (Dynamic Feature Extraction)" .work/test-coverage/gaps/test-gaps-report.html && \
echo "✓ Feature extraction section present" || \
echo "✗ MISSING: Dynamic Feature Extraction section"
# Verify JSON has feature data
grep -q '"tested_features"' .work/test-coverage/gaps/test-gaps-report.json && \
grep -q '"feature_gaps"' .work/test-coverage/gaps/test-gaps-report.json && \
echo "✓ Feature data in JSON" || \
echo "✗ MISSING: Feature data in JSON"
# Verify Text has feature section
grep -q "Tested Features" .work/test-coverage/gaps/test-gaps-summary.txt && \
echo "✓ Feature section in Text" || \
echo "✗ MISSING: Feature section in Text"
Required: Dynamic Feature Extraction must be present in all three reports. This is a critical requirement from Step 5a (lines 163-280).
3. HTML Coverage Dimension Verification
CRITICAL: The HTML report must display ALL coverage dimension tables based on component type.
# For networking components, verify ALL 8 dimension tables exist
grep -c "<h3>Platforms</h3>" .work/test-coverage/gaps/test-gaps-report.html
grep -c "<h3>Protocols</h3>" .work/test-coverage/gaps/test-gaps-report.html
grep -c "<h3>Service Types</h3>" .work/test-coverage/gaps/test-gaps-report.html
grep -c "<h3>IP Stacks</h3>" .work/test-coverage/gaps/test-gaps-report.html
grep -c "<h3>Network Layers</h3>" .work/test-coverage/gaps/test-gaps-report.html
grep -c "<h3>Gateway Modes</h3>" .work/test-coverage/gaps/test-gaps-report.html
grep -c "<h3>Topologies</h3>" .work/test-coverage/gaps/test-gaps-report.html
grep -c "<h3>Scenarios</h3>" .work/test-coverage/gaps/test-gaps-report.html
Expected Results:
- Networking components: 8 dimension tables (Platforms, Protocols, Service Types, IP Stacks, Network Layers, Gateway Modes, Topologies, Scenarios)
- Storage components: 5 dimension tables (Platforms, Storage Classes, Volume Modes, Provisioners, Scenarios)
- Other components: 2 dimension tables (Platforms, Scenarios)
Verification Command:
# Count total coverage dimension tables
TABLE_COUNT=$(grep -E "<h3>(Platforms|Protocols|Service Types|IP Stacks|Network Layers|Gateway Modes|Topologies|Scenarios|Storage Classes|Volume Modes|Provisioners)</h3>" .work/test-coverage/gaps/test-gaps-report.html | wc -l)
echo "Coverage dimension tables found: $TABLE_COUNT"
# Verify based on component type
COMPONENT=$(grep -oP 'Component:</strong> \K[^<]+' .work/test-coverage/gaps/test-gaps-report.html | head -1 | tr -d '</p>')
echo "Component type: $COMPONENT"
case "$COMPONENT" in
Networking)
[ "$TABLE_COUNT" -eq 8 ] && echo "✓ All 8 networking dimensions present" || echo "✗ INCOMPLETE: Expected 8 tables, found $TABLE_COUNT"
;;
Storage)
[ "$TABLE_COUNT" -eq 5 ] && echo "✓ All 5 storage dimensions present" || echo "✗ INCOMPLETE: Expected 5 tables, found $TABLE_COUNT"
;;
*)
[ "$TABLE_COUNT" -eq 2 ] && echo "✓ All 2 generic dimensions present" || echo "✗ INCOMPLETE: Expected 2 tables, found $TABLE_COUNT"
;;
esac
Required: All component-specific dimension tables must be present. Missing tables indicate incomplete HTML generation.
4. Effort Estimates Verification
# Verify gaps include effort estimates
grep -q "Effort Required" .work/test-coverage/gaps/test-gaps-report.html && \
echo "✓ Effort estimates in HTML" || \
echo "✗ MISSING: Effort estimates"
Required: Gaps must include effort estimates (Low, Medium, High) as specified in Step 5a.
5. Gap Analyzer Implementation Verification
# Verify analyzer has feature extraction function
grep -q "def extract_features_from_tests" .work/test-coverage/gaps/gap_analyzer.py && \
echo "✓ Feature extraction function exists" || \
echo "✗ MISSING: extract_features_from_tests() function"
# Verify all 5 feature categories are defined
grep -q "Configuration Patterns" .work/test-coverage/gaps/gap_analyzer.py && \
grep -q "Network Topology" .work/test-coverage/gaps/gap_analyzer.py && \
grep -q "Lifecycle Operations" .work/test-coverage/gaps/gap_analyzer.py && \
grep -q "Network Features" .work/test-coverage/gaps/gap_analyzer.py && \
grep -q "Resilience & Recovery" .work/test-coverage/gaps/gap_analyzer.py && \
echo "✓ All 5 feature categories defined" || \
echo "✗ MISSING: Some feature categories not implemented"
Required: The gap analyzer must implement Dynamic Feature Extraction with all 5 categories.
6. JSON Structure Verification
# Verify JSON has all required fields
python3 << 'EOF'
import json
try:
with open('.work/test-coverage/gaps/test-gaps-report.json', 'r') as f:
data = json.load(f)
required_fields = [
('analysis.file', lambda d: d['analysis']['file']),
('analysis.component_type', lambda d: d['analysis']['component_type']),
('analysis.test_count', lambda d: d['analysis']['test_count']),
('analysis.tested_features', lambda d: d['analysis']['tested_features']),
('analysis.feature_gaps', lambda d: d['analysis']['feature_gaps']),
('scores.overall', lambda d: d['scores']['overall']),
]
missing = []
for name, getter in required_fields:
try:
getter(data)
print(f"✓ {name}")
except (KeyError, TypeError):
print(f"✗ MISSING: {name}")
missing.append(name)
if not missing:
print("\n✓ All required JSON fields present")
else:
print(f"\n✗ INCOMPLETE: Missing {len(missing)} required fields")
exit(1)
except Exception as e:
print(f"✗ ERROR: {e}")
exit(1)
EOF
Required: All required JSON fields must be present.
Validation Summary
Before declaring this skill complete:
- ✓ All three report files exist
- ✓ Dynamic Feature Extraction present in all reports
- ✓ HTML shows ALL component-specific coverage dimension tables
- ✓ Effort estimates included in gaps
- ✓ Gap analyzer implements feature extraction function
- ✓ JSON contains all required fields
If ANY check fails: Fix the issue and re-run all validation checks. Do NOT declare the skill complete until ALL checks pass.
Error Handling
Common Issues and Solutions
File not found:
- Verify the test file path is correct
- Check that the file exists and is readable
Invalid file format:
- Ensure the file is a Go test file (
.go)
- Check that the file uses Ginkgo framework (
g.It, g.Describe)
No test cases found:
- Verify the file contains Ginkgo test cases
- Check for
g.It("...") patterns
Examples
Example 1: Analyze Networking Test File
# Run gap analyzer on a networking test file
cd /home/anusaxen/git/ai-helpers/plugins/test-coverage
python3 .work/test-coverage/gaps/gap_analyzer.py \
/path/to/test/extended/networking/egressip_test.go \
--output .work/gaps/
# Output:
# Component detected: networking
# Test cases found: 25
# Overall coverage: 45.0%
# High-priority gaps: Azure platform, UDP protocol, Error handling scenarios
#
# Reports generated:
# HTML: .work/gaps/test-gaps-report.html
# JSON: .work/gaps/test-gaps-report.json
# Text: .work/gaps/test-gaps-summary.txt
Example 2: Analyze Storage Test File
# Run gap analyzer on a storage test file
python3 .work/test-coverage/gaps/gap_analyzer.py \
/path/to/test/extended/storage/persistent_volumes_test.go \
--output .work/gaps/
# Output:
# Component detected: storage
# Test cases found: 18
# Overall coverage: 52.0%
# High-priority gaps: ReadWriteMany volumes, CSI storage class, Snapshot scenarios
Example 3: Analyze from GitHub URL
# Analyze file from GitHub raw URL
python3 .work/test-cove
…(truncated)
1---2name: component-aware-test-gap-analysis3description: Intelligently identify missing test coverage based on component type Use when this capability is needed.4---56# Component-Aware Test Gap Analysis Skill78This skill **automatically detects component type** (networking, storage, API, etc.) and provides **context-aware gap analysis**. It analyzes e2e test files to identify missing test coverage specific to the component being tested.910## When to Use This Skill1112Use this skill when you need to:13- **Automatically detect component type** from test file path and content14- **Component-specific gap analysis**:15 - **Networking**: Identify missing protocol tests (TCP, UDP, SCTP), service type coverage, IP stack testing16 - **Storage**: Find gaps in storage class coverage, volume mode testing, provisioner tests17 - **Generic**: Analyze platform coverage and common scenarios for other components18- **Always analyze**: Cloud platform coverage (AWS, Azure, GCP, etc.) and scenario testing (error handling, upgrades, RBAC, scale)19- Prioritize testing efforts based on component-specific production importance20- Generate comprehensive component-aware gap analysis reports2122## ⚠️ CRITICAL REQUIREMENT2324**This skill MUST ALWAYS generate all three report formats (HTML, JSON, and Text) at runtime.**2526The gap analyzer script (generated at runtime to `.work/test-coverage/gaps/gap_analyzer.py`) performs the analysis and returns structured data. Claude Code is responsible for generating all three report formats based on this data.2728**Required Actions:**291. ✅ **Execute**: `python3 .work/test-coverage/gaps/gap_analyzer.py <test-file> --output-json` (outputs structured JSON to stdout)302. ✅ **Generate**: Create all three report files (HTML, JSON, Text) at runtime313. ✅ **Verify**: All three reports are generated successfully324. ✅ **Display**: Show report locations and summary to the user3334**Failure to generate any of the three report formats** should be treated as a skill execution failure.3536## Prerequisites3738### Required Tools3940- **Python 3.8+** for test structure analysis41- **Go toolchain** for the target project4243### Installation4445```bash46# Python dependencies (standard library only, no external packages required)47# Ensure Python 3.8+ is installed4849# Optional Go analysis tools50go install golang.org/x/tools/cmd/guru@latest51go install golang.org/x/tools/cmd/goimports@latest52```5354## How It Works5556**Note: This skill currently supports E2E/integration test files for OpenShift/Kubernetes components written in Go (Ginkgo framework).**5758### Current Implementation5960The analyzer performs **single test file analysis** with two analysis layers:61621. **Generic Coverage Analysis** (keyword-based)63 - Platforms, protocols, IP stacks, service types64 - Uses regex pattern matching on file content65662. **Feature-Based Analysis** (runtime extraction)67 - Dynamically extracts features from test names68 - Infers missing features based on patterns69 - No hardcoded feature matrices - works for ANY component7071It does **not** perform repository traversal, Go AST parsing, or test-to-source mapping.7273### Analysis Flow7475#### Step 1: Component Type Detection7677The analyzer automatically detects the component type from:78791. **File path patterns**:80 - `/networking/` → networking component81 - `/storage/` → storage component82 - `/kapi/`, `/api/` → kube-api component83 - `/etcd/` → etcd component84 - `/auth/`, `/rbac/` → auth component85862. **File content patterns**:87 - Keywords like `sig-networking`, `networkpolicy`, `egressip` → networking88 - Keywords like `sig-storage`, `persistentvolume` → storage89 - Keywords like `sig-api`, `apiserver` → kube-api9091#### Step 2: Extract Test Cases9293Parses the test file using regex to extract:9495- **Test names** from Ginkgo `g.It("test name")` patterns96- **Line numbers** where tests are defined97- **Test tags** like `[Serial]`, `[Disruptive]`, `[NonPreRelease]`98- **Test IDs** from patterns like `-12345-` in test names99100**Example:**101```go102g.It("egressip-12345-should work on AWS [Serial]", func() {103 // Test implementation104})105```106107Extracted:108- Name: `egressip-12345-should work on AWS [Serial]`109- ID: `12345`110- Tags: `[Serial]`111- Line: 42112113#### Step 3: Analyze Coverage Using Regex114115For each component type, the analyzer searches the file content for specific keywords to determine what is tested:116117**Networking components:**118- **Platforms**: `vsphere`, `AWS`, `azure`, `GCP`, `baremetal`119- **Protocols**: `TCP`, `UDP`, `SCTP`120- **Service types**: `NodePort`, `LoadBalancer`, `ClusterIP`121- **Scenarios**: `invalid`, `upgrade`, `concurrent`, `performance`, `rbac`122123**Storage components:**124- **Platforms**: `vsphere`, `AWS`, `azure`, `GCP`, `baremetal`125- **Storage classes**: `gp2`, `gp3`, `csi`126- **Volume modes**: `ReadWriteOnce`, `ReadWriteMany`, `ReadOnlyMany`127- **Scenarios**: `invalid`, `upgrade`, `concurrent`, `performance`, `rbac`128129**Other components:**130- **Platforms**: `vsphere`, `AWS`, `azure`, `GCP`, `baremetal`131- **Scenarios**: `invalid`, `upgrade`, `concurrent`, `performance`, `rbac`132133#### Step 4: Identify Gaps134135For each coverage dimension, if a keyword is **not found** in the file, it's flagged as a gap:136137**Example:**138```python139# If file content doesn't contain "azure" (case-insensitive)140gaps.append({141 'platform': 'Azure',142 'priority': 'high',143 'impact': 'Major cloud provider - production blocker',144 'recommendation': 'Add Azure platform-specific tests'145})146```147148#### Step 5: Calculate Component-Aware Coverage Scores149150Scoring is component-specific to avoid penalizing components for irrelevant metrics:151152**Networking components:**153- Overall = avg(platform_score, protocol_score, service_type_score, scenario_score)154155**Storage components:**156- Overall = avg(platform_score, storage_class_score, volume_mode_score, scenario_score)157158**Other components:**159- Overall = avg(platform_score, scenario_score)160161Each dimension score = (items_found / total_items) × 100162163#### Step 5a: Dynamic Feature Extraction (Runtime Analysis)164165In addition to the keyword-based coverage analysis above, the analyzer performs **dynamic feature extraction** to identify component-specific features from test names at runtime, without any hardcoded feature matrices.166167**How Runtime Feature Extraction Works:**1681691. **Extract Features from Test Names**170171 Parse test names to identify features being tested:172173 **Example Test Name:**174 ```175 "Validate egressIP with mixed of multiple non-overlapping UDNs and default network(layer3/2 and IPv4 only)"176 ```177178 **Extracted Features:**179 - ✓ Non-overlapping configuration180 - ✓ Multiple resource configuration181 - ✓ Mixed configuration182 - ✓ User Defined Networks (UDN)183 - ✓ Default network184 - ✓ Layer 3 networking1851862. **Group Features into Categories**187188 Features are automatically categorized:189190 - **Configuration Patterns**: overlapping, non-overlapping, single, multiple, mixed191 - **Network Topology**: UDN, default network, layer2, layer3, gateway modes192 - **Lifecycle Operations**: creation, deletion, recreation, assignment193 - **Network Features**: failover, load balancing, isolation194 - **Resilience & Recovery**: reboot, restart, node deletion1951963. **Infer Missing Features**197198 Based on patterns, infer what's missing:199200 - **Opposite patterns**: If "overlapping" tested → suggest "non-overlapping"201 - **Single vs Multiple**: If "single resource" tested → suggest "multiple resources"202 - **Completeness**: If "deletion" tested → suggest "recreation"203 - **Layer coverage**: If "layer2" tested → suggest "layer3"204205**Benefits of Runtime Feature Extraction:**206207✅ **No Hardcoding** - Works for ANY component without configuration208✅ **Intelligent Gap Detection** - Infers missing features based on patterns209✅ **Component-Agnostic** - Automatically adapts to any component type210✅ **Always Current** - Extracts from actual test names, not assumed features211212**Example: EgressIP Test Analysis**213214**Input (Test Names):**215```2161. Validate egressIP with mixed of multiple non-overlapping UDNs2172. Validate egressIP with mixed of multiple overlapping UDNs2183. Validate egressIP Failover with UDNs2194. egressIP after UDN deleted then recreated2205. egressIP after OVNK restarted2216. Traffic is load balanced between egress nodes222```223224**Output (Extracted Features):**225```226Configuration Patterns:227 ✓ Non-overlapping configuration228 ✓ Overlapping configuration229 ✓ Multiple resource configuration230 ✓ Mixed configuration231232Network Topology:233 ✓ User Defined Networks (UDN)234235Lifecycle Operations:236 ✓ Resource deletion237 ✓ Resource recreation238239Network Features:240 ✓ Failover241 ✓ Load balancing242243Resilience & Recovery:244 ✓ OVN-Kubernetes restart245```246247**Output (Inferred Feature Gaps):**248```249[HIGH] Single resource configuration250 - Pattern suggests "multiple" tested but not "single"251 - Recommendation: Add single resource baseline tests252253[HIGH] Layer 2 networking254 - Layer 3 tested but Layer 2 missing255 - Recommendation: Add Layer 2 network topology tests256257[MEDIUM] Local gateway mode258 - Gateway mode mentioned but local vs shared not clear259 - Recommendation: Add explicit gateway mode tests260```261262**Integration in gap_analyzer.py:**263264The dynamic feature extractor is built into the analyzer (no separate import needed):265266```python267# After extracting test cases268feature_analysis = extract_features_from_tests(test_cases)269270# Results included in analysis output271tested_features = feature_analysis['tested_features']272# {'Configuration Patterns': ['Overlapping', 'Non-overlapping', ...],273# 'Network Topology': ['UDN', 'Layer3', ...]}274275feature_gaps = feature_analysis['feature_gaps']276# [{'feature': 'Multiple resources', 'priority': 'high', ...}]277278coverage_stats = feature_analysis['coverage_stats']279# {'features_tested': 14, 'features_missing': 5}280```281282**Report Integration:**283284Feature analysis is included in all three report formats:285286- **HTML Reports**: Feature sections with tested/missing features287- **Text Reports**: Feature lists grouped by category288- **JSON Reports**: Structured feature data for CI/CD integration289290### Limitations291292The current implementation has the following limitations:293294❌ **No repository traversal** - Analyzes only the single test file provided as input295❌ **No Go AST parsing** - Uses regex pattern matching instead of parsing Go syntax trees296❌ **No test-to-source mapping** - Cannot map test functions to source code functions297❌ **No function-level coverage** - Cannot determine which source functions are tested298❌ **No project-wide analysis** - Cannot analyze multiple test files or aggregate results299❌ **Keyword-based detection only** - Gap detection relies on keyword presence in test file300❌ **Single file focus** - Reports cover only the analyzed test file, not the entire codebase301302These limitations mean the analyzer provides **scenario and platform coverage analysis** for a single E2E test file, not structural code coverage across a codebase.303304#### Step 6: Generate Reports305306The analyzer generates three report formats. You should generate Python code at runtime to create these reports.307308#### 1. HTML Gap Report (`test-gaps-report.html`)309310**Purpose:** Interactive, filterable HTML report for visual gap analysis with professional styling311312**HTML Document Structure:**313314Generate a complete HTML5 document with the following structure:315316```html317<!DOCTYPE html>318<html lang="en">319<head>320 <meta charset="UTF-8">321 <meta name="viewport" content="width=device-width, initial-scale=1.0">322 <title>Test Coverage Gap Analysis - {filename}</title>323 <style>324 /* Inline all CSS styles here - see CSS Styles section below */325 </style>326</head>327<body>328 <div class="container">329 <!-- Content sections -->330 </div>331 <script>332 /* JavaScript for gap filtering - see JavaScript section below */333 </script>334</body>335</html>336```337338**CSS Styles (Inline in `<style>` tag):**339340Generate comprehensive CSS with the following style rules:3413421. **Reset and Base Styles:**343 - `*`: box-sizing: border-box, margin: 0, padding: 0344 - `body`: font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; background: #f5f5f5; padding: 20px3453462. **Container and Layout:**347 - `.container`: max-width: 1400px, margin: 0 auto, background: white, padding: 30px, border-radius: 8px, box-shadow: 0 2px 10px rgba(0,0,0,0.1)348 - `h1`: color: #2c3e50, margin-bottom: 10px, font-size: 2em349 - `h2`: color: #34495e, margin-top: 30px, margin-bottom: 15px, padding-bottom: 10px, border-bottom: 2px solid #e74c3c, font-size: 1.5em350 - `h3`: color: #34495e, margin-top: 20px, margin-bottom: 10px, font-size: 1.2em3513523. **Metadata Section:**353 - `.metadata`: background: #ecf0f1, padding: 15px, border-radius: 5px, margin-bottom: 25px354 - `.metadata p`: margin: 5px 03553564. **Score Cards:**357 - `.score-grid`: display: grid, grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)), gap: 15px, margin: 20px 0358 - `.score-card`: padding: 20px, border-radius: 8px, text-align: center, color: white359 - `.score-card.excellent`: background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%) (score >= 80)360 - `.score-card.good`: background: linear-gradient(135deg, #3498db 0%, #2980b9 100%) (score >= 60)361 - `.score-card.fair`: background: linear-gradient(135deg, #f39c12 0%, #e67e22 100%) (score >= 40)362 - `.score-card.poor`: background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%) (score < 40)363 - `.score-card .number`: font-size: 2.5em, font-weight: bold, margin: 10px 0364 - `.score-card .label`: font-size: 0.9em, opacity: 0.93653665. **Gap Cards:**367 - `.gap-card`: background: #fff, border-left: 4px solid #e74c3c, padding: 20px, margin: 15px 0, border-radius: 5px, box-shadow: 0 2px 5px rgba(0,0,0,0.1)368 - `.gap-card.high`: border-left-color: #e74c3c369 - `.gap-card.medium`: border-left-color: #f39c12370 - `.gap-card.low`: border-left-color: #3498db371 - `.gap-card h4`: color: #2c3e50, margin-bottom: 10px, font-size: 1.1em372 - `.gap-card .gap-id`: font-family: "Courier New", monospace, font-size: 0.85em, color: #7f8c8d, margin-bottom: 5px373 - `.priority`: display: inline-block, padding: 4px 12px, border-radius: 12px, font-size: 0.75em, font-weight: bold, margin-right: 8px374 - `.priority.high`: background: #e74c3c, color: white375 - `.priority.medium`: background: #f39c12, color: white376 - `.priority.low`: background: #3498db, color: white377 - `.gap-card .impact`: background: #fff3cd, border-left: 3px solid #ffc107, padding: 10px, margin: 10px 0, border-radius: 3px378 - `.gap-card .recommendation`: background: #d4edda, border-left: 3px solid #28a745, padding: 10px, margin: 10px 0, border-radius: 3px3793806. **Tables:**381 - `table`: width: 100%, border-collapse: collapse, margin: 20px 0382 - `th, td`: padding: 12px, text-align: left, border-bottom: 1px solid #ddd383 - `th`: background: #34495e, color: white, font-weight: 600384 - `tr:hover`: background: #f5f5f5385 - `.tested`: background: #d4edda, color: #155724, font-weight: bold, text-align: center386 - `.not-tested`: background: #f8d7da, color: #721c24, font-weight: bold, text-align: center3873887. **Summary Boxes:**389 - `.summary-box`: background: #e3f2fd, border-left: 4px solid #2196f3, padding: 15px, margin: 20px 0, border-radius: 5px390 - `.warning-box`: background: #fff3cd, border-left: 4px solid #ffc107, padding: 15px, margin: 20px 0, border-radius: 5px391 - `.success-box`: background: #d4edda, border-left: 4px solid #28a745, padding: 15px, margin: 20px 0, border-radius: 5px3923938. **Filter Buttons:**394 - `.filter-buttons`: margin: 20px 0395 - `.filter-btn`: padding: 10px 20px, margin-right: 10px, border: none, border-radius: 5px, cursor: pointer, font-weight: bold396 - `.filter-btn.active`: box-shadow: 0 0 0 3px rgba(0,0,0,0.2)397 - `.filter-btn.all`: background: #95a5a6, color: white398 - `.filter-btn.high`: background: #e74c3c, color: white399 - `.filter-btn.medium`: background: #f39c12, color: white400 - `.filter-btn.low`: background: #3498db, color: white401402**HTML Content Sections:**4034041. **Metadata Section:**405 ```html406 <div class="metadata">407 <p><strong>File:</strong> <code>{escaped_filename}</code></p>408 <p><strong>Path:</strong> <code>{escaped_filepath}</code></p>409 <p><strong>Component:</strong> {escaped_component_title}</p>410 <p><strong>Analysis Date:</strong> {YYYY-MM-DD}</p>411 <p><strong>Total Test Cases:</strong> {count}</p>412 </div>413 ```4144152. **Coverage Scores Section:**416 - Display score cards in a grid417 - Show scores dynamically based on what's calculated for the component418 - Score display order and labels:419 ```python420 SCORE_DISPLAY = {421 'overall': {'order': 1, 'label': 'Overall Coverage'},422 'platform_coverage': {'order': 2, 'label': 'Platform Coverage'},423 'ip_stack_coverage': {'order': 3, 'label': 'IP Stack Coverage'},424 'topology_coverage': {'order': 4, 'label': 'Topology Coverage'},425 'network_layer_coverage': {'order': 5, 'label': 'Network Layer Coverage'},426 'gateway_mode_coverage': {'order': 6, 'label': 'Gateway Mode Coverage'},427 'protocol_coverage': {'order': 5, 'label': 'Protocol Coverage'},428 'service_type_coverage': {'order': 6, 'label': 'Service Type Coverage'},429 'storage_class_coverage': {'order': 7, 'label': 'Storage Class Coverage'},430 'volume_mode_coverage': {'order': 8, 'label': 'Volume Mode Coverage'},431 'scenario_coverage': {'order': 99, 'label': 'Scenario Coverage'},432 }433 ```434 - Sort scores by order, render only non-zero/non-None scores435 - Apply CSS class based on score value: `get_score_class(score)`436 - If overall < 60%, add a warning box with key findings4374383. **What's Tested Section:**439 - Generate tables showing tested vs not-tested items440 - For networking components: platforms, protocols, service types, IP stacks, topologies, scenarios441 - For storage components: platforms, storage classes, volume modes, scenarios442 - For other components: platforms, scenarios only443 - Table format:444 ```html445 <table>446 <tr>447 <th>Item</th>448 <th>Status</th>449 </tr>450 <tr>451 <td>AWS</td>452 <td class="tested">✓ Tested</td>453 </tr>454 </table>455 ```4564574. **Coverage Gaps Section:**458 - Summary box with gap counts by priority459 - Filter buttons for All/High/Medium/Low priority460 - Gap cards with data-priority attribute for filtering:461 ```html462 <div class="gap-card {priority}" data-priority="{priority}">463 <div class="gap-id">GAP-{001}</div>464 <h4>465 <span class="priority {priority}">{PRIORITY} PRIORITY</span>466 <span class="category">{Category}</span>467 {gap_name}468 </h4>469 <div class="impact"><strong>Impact:</strong> {impact_description}</div>470 <div class="recommendation"><strong>Recommendation:</strong> {recommendation_text}</div>471 </div>472 ```473 - Assign sequential GAP IDs: GAP-001, GAP-002, etc.474 - Sort gaps by priority (high, medium, low)4754765. **Recommendations Section:**477 - Success box with top 5 high-priority gaps listed478 - Bulleted list of immediate actions479480**JavaScript for Filtering (Inline in `<script>` tag):**481482```javascript483function filterGaps(priority) {484 const cards = document.querySelectorAll('.gap-card');485 const buttons = document.querySelectorAll('.filter-btn');486487 buttons.forEach(btn => btn.classList.remove('active'));488 document.querySelector(`.filter-btn.${priority}`).classList.add('active');489490 cards.forEach(card => {491 if (priority === 'all' || card.dataset.priority === priority) {492 card.style.display = 'block';493 } else {494 card.style.display = 'none';495 }496 });497}498```499500**Security Requirements:**501- Use `html.escape()` for all user-provided content (filenames, test names, gap descriptions)502- Sanitize priority values to only allow: 'high', 'medium', 'low'503- Never inject raw HTML from analysis data504505**Helper Functions to Implement:**5065071. `get_score_class(score)`:508 - score >= 80: return 'excellent'509 - score >= 60: return 'good'510 - score >= 40: return 'fair'511 - else: return 'poor'5125132. Escape all strings using `from html import escape`514515**Component-Specific Behavior:**516517- **Networking components** (networking, router, dns, network-observability):518 - Show: platforms, protocols, service types, IP stacks, topologies, network layers, gateway modes, scenarios519520- **Storage components** (storage, csi):521 - Show: platforms, storage classes, volume modes, volumes, CSI drivers, snapshots, scenarios522523- **Other components**:524 - Show: platforms, scenarios only525526#### 2. JSON Report (`test-gaps-report.json`)527528**Generated by:** Claude Code at runtime based on analyzer output529530**Purpose:** Machine-readable format for CI/CD integration531532**Structure:**533```json534{535 "analysis": {536 "file": "path/to/test/file.go",537 "component_type": "networking",538 "test_count": 15,539 "test_cases": [540 {541 "name": "test name",542 "line": 42,543 "id": "12345",544 "tags": ["Serial", "Disruptive"]545 }546 ],547 "coverage": {548 "platforms": {549 "tested": ["AWS", "GCP"],550 "not_tested": ["Azure", "vSphere", "Bare Metal"]551 },552 "protocols": {553 "tested": ["TCP"],554 "not_tested": ["UDP", "SCTP"]555 }556 },557 "gaps": {558 "platforms": [559 {560 "platform": "Azure",561 "priority": "high",562 "impact": "Major cloud provider",563 "recommendation": "Add Azure tests"564 }565 ],566 "protocols": [],567 "scenarios": []568 }569 },570 "scores": {571 "overall": 45.0,572 "platform_coverage": 33.3,573 "protocol_coverage": 33.3,574 "scenario_coverage": 40.0575 },576 "generated_at": "2025-11-10T10:00:00Z"577}578```579580**Implementation:** Use `json.dump()` with `indent=2` for readable output581582#### 3. Text Summary (`test-gaps-summary.txt`)583584**Generated by:** Claude Code at runtime based on analyzer output585586**Purpose:** Terminal-friendly summary for quick review587588**Format Structure:**589```text590============================================================591Test Coverage Gap Analysis592============================================================593594File: {filename}595Component: {component_type}596Test Cases: {count}597Analysis Date: {timestamp}598599============================================================600Coverage Scores601============================================================602603Overall Coverage: {score}%604Platform Coverage: {score}%605[Component-specific scores based on type]606Scenario Coverage: {score}%607608============================================================609What's Tested610============================================================611612Platforms:613 ✓ {platform1}614 ✓ {platform2}615616[Additional tested items based on component type]617618============================================================619Identified Gaps620============================================================621622PLATFORM GAPS:623 [PRIORITY] {platform}624 Impact: {impact}625 Recommendation: {recommendation}626627[Additional gap sections based on component type]628629============================================================630Recommendations631============================================================632633Current Coverage: {current}%634Target Coverage: {target}%635636Focus on addressing HIGH priority gaps first to maximize637test coverage and ensure production readiness.638```639640**Component-Specific Sections:**641- **Networking components**: Include protocol, service type, IP stack, topology gaps642- **Storage components**: Include storage class, volume mode gaps643- **Other components**: Only include platform and scenario gaps644645**Implementation:** Use `'\n'.join(lines)` to build the text content646647## Implementation Steps648649When implementing this skill in a command:650651### Step 0: Generate Analyzer Script at Runtime652653**CRITICAL:** Before running any analysis, generate the analyzer script from the reference implementation.654655```bash656# Create output directory657mkdir -p .work/test-coverage/gaps/658659# Generate the analyzer script from the specification below660# Claude Code will write gap_analyzer.py based on the Analyzer Specification section661```662663**Analyzer Specification:**664665Generate a Python script (`gap_analyzer.py`) that performs component-aware E2E test gap analysis:666667**Input:** Path or URL to a Go test file (Ginkgo framework)668**Output:** JSON to stdout with analysis results and coverage scores669670**Core Algorithm:**6716720. **Input Processing** (handle URLs and local paths):673 - Check if input starts with `http://` or `https://`674 - If URL: Use `urllib.request.urlopen()` to fetch content, save to temp file675 - If local path: Use directly676 - After analysis: Clean up temp file if created6776781. **Component Detection** (auto-detect from file path/content):679 - Networking: `/networking/`, `egressip`, `networkpolicy` → component_type='networking'680 - Storage: `/storage/`, `persistentvolume` → component_type='storage'681 - Other components: etcd, apiserver, mco, operators, etc.6826832. **Test Extraction** (regex-based):684 - Pattern: `(?:g\.|o\.)?It\(\s*["']([^"']+)["']`685 - Extract: test name, line number, tags ([Serial], [Disruptive]), test ID (pattern: `-\d+-`)6866873. **Coverage Analysis** (keyword search in file content):688 - **Platforms**: Search for `aws|azure|gcp|vsphere|baremetal|rosa` (case-insensitive)689 - **Protocols**: Search for `\bTCP\b`, `\bUDP\b`, `\bSCTP\b`, `curl|wget|http` (TCP via HTTP)690 - **IP Stacks**: Search for `ipv4`, `ipv6`, `dualstack`691 - **Service Types**: Search for `NodePort`, `LoadBalancer`, `ClusterIP`692 - **Network Layers** (networking only): `layer2|l2`, `layer3|l3`, `default network`693 - **Gateway Modes** (networking only):694 - Search for `local.gateway|lgw` → if found, Local Gateway is tested695 - Shared Gateway is DEFAULT in OVN-K: if tests exist but no local gateway pattern found → Shared Gateway is tested696 - If no tests exist → neither is tested697 - **Topologies**: `sno|single-node`, `multi-node|HA cluster`, `hypershift|hcp`, check NonHyperShiftHOST tag698 - **Scenarios**: `failover`, `reboot`, `restart`, `delete`, `invalid`, `upgrade`, `concurrent`, `performance`, `rbac`, `traffic disruption`6997004. **Gap Identification**:701 - For each category, items NOT found = gaps702 - Assign priority: high (production-critical), medium (important), low (nice-to-have)703 - Platform gaps: Azure/GCP/AWS = high, vSphere/Bare Metal = medium704 - Protocol gaps: UDP = high, SCTP = medium, TCP non-HTTP = low705 - Service type gaps: LoadBalancer = high, others = medium706 - Scenario gaps: Error Handling = high, Traffic Disruption = high (networking only)7077085. **Coverage Scoring** (component-aware):709 - Networking: avg(platform, protocol, service_type, ip_stack, network_layer, gateway_mode, topology, scenario)710 - Storage: avg(platform, storage_class, volume_mode, scenario)711 - Other: avg(platform, scenario)712 - Each dimension: (tested_count / total_count) × 1007137146. **Output Format** (JSON to stdout):715```json716{717 "analysis": {718 "file": "/path/to/test.go",719 "component_type": "networking",720 "test_count": 15,721 "test_cases": [...],722 "coverage": {723 "platforms": {"tested": [...], "not_tested": [...]},724 "protocols": {"tested": [...], "not_tested": [...]},725 ...726 },727 "gaps": {728 "platforms": [{"platform": "Azure", "priority": "high", "impact": "...", "recommendation": "..."}],729 ...730 }731 },732 "scores": {733 "overall": 62.0,734 "platform_coverage": 100.0,735 ...736 }737}738```739740**Why Runtime Generation:**741- Claude Code generates the analyzer from this specification742- No separate `.py` file to maintain743- SKILL.md is the single source of truth744- Claude Code is excellent at generating code from specifications745746### Step 1: Execute Gap Analyzer Script (MANDATORY)747748**Execute the gap analyzer script to perform analysis and return structured data:**749750```bash751# Run gap analyzer (outputs structured JSON to stdout)752python3 .work/test-coverage/gaps/gap_analyzer.py <test-file-path> --output-json753```754755The analyzer will output structured JSON to stdout containing:756- Component type detection757- Test case extraction758- Coverage analysis759- Gap identification760- Priority scoring761- Component-specific recommendations762763**IMPORTANT:** Do not skip this step. Do not attempt manual analysis. The script is the authoritative implementation.764765### Step 2: Capture and Parse Analyzer Output766767```python768import json769import subprocess770771# Run analyzer and capture JSON output772result = subprocess.run(773 ['python3', '.work/test-coverage/gaps/gap_analyzer.py', test_file, '--output-json'],774 capture_output=True,775 text=True776)777778# Parse structured data779analysis_data = json.loads(result.stdout)780```781782### Step 3: Generate All Three Report Formats at Runtime (MANDATORY)783784**IMPORTANT:** Claude Code generates all three report formats based on the analyzer's structured output.785786#### 3.1: Generate JSON Report787788```python789json_path = '.work/test-coverage/gaps/test-gaps-report.json'790with open(json_path, 'w') as f:791 json.dump(analysis_data, f, indent=2)792```793794#### 3.2: Generate Text Summary Report795796Follow the text format specification in Step 6 to generate a terminal-friendly summary.797798```python799text_path = '.work/test-coverage/gaps/test-gaps-summary.txt'800# Generate text content following format in Step 6801with open(text_path, 'w') as f:802 f.write(text_content)803```804805#### 3.3: Generate HTML Report806807Follow the HTML specification in Step 6 to generate an interactive report.808809```python810html_path = '.work/test-coverage/gaps/test-gaps-report.html'811# Generate HTML content following specification in Step 6812# Include all CSS styles, JavaScript filtering, and component-specific sections813with open(html_path, 'w') as f:814 f.write(html_content)815```816817**Key Requirements:**818- Generate HTML following the exact structure in "Step 6: Generate Reports" above819- Include all CSS styles inline in `<style>` tag820- Include JavaScript filtering function in `<script>` tag821- Escape all user-provided content with `html.escape()`822- Apply component-specific sections based on component type823824### Step 4: Display Results825826After generating all three reports, display the results to the user:827828```python829# Display summary (from text report or analysis_data)830print(f"Component detected: {analysis_data['analysis']['component_type']}")831print(f"Overall coverage: {analysis_data['scores']['overall']}%")832print(f"High-priority gaps: {high_priority_count}")833834# Provide report locations835print("\nReports Generated:")836print(" ✓ HTML: .work/test-coverage/gaps/test-gaps-report.html")837print(" ✓ JSON: .work/test-coverage/gaps/test-gaps-report.json")838print(" ✓ Text: .work/test-coverage/gaps/test-gaps-summary.txt")839```840841### Step 5: Parse Analysis Data (Optional)842843For programmatic access to gap data, use the `analysis_data` from Step 2:844845```python846# Access analysis results (from analysis_data captured in Step 2)847component_type = analysis_data['analysis']['component_type']848test_count = analysis_data['analysis']['test_count']849overall_score = analysis_data['scores']['overall']850851# Access gaps852platform_gaps = analysis_data['analysis']['gaps']['platforms']853protocol_gaps = analysis_data['analysis']['gaps'].get('protocols', [])854scenario_gaps = analysis_data['analysis']['gaps']['scenarios']855856# Filter high-priority gaps857high_priority_gaps = [858 gap for category in analysis_data['analysis']['gaps'].values()859 for gap in category if gap.get('priority') == 'high'860]861```862863## ⚠️ MANDATORY PRE-COMPLETION VALIDATION864865**CRITICAL:** Before declaring this skill complete, you MUST execute ALL validation checks below. Failure to validate is considered incomplete execution.866867### Validation Checklist868869Execute these verification steps in order. ALL must pass:870871#### 1. File Existence Check872873```bash874# Verify all three reports exist875test -f .work/test-coverage/gaps/test-gaps-report.html && echo "✓ HTML exists" || echo "✗ HTML MISSING"876test -f .work/test-coverage/gaps/test-gaps-report.json && echo "✓ JSON exists" || echo "✗ JSON MISSING"877test -f .work/test-coverage/gaps/test-gaps-summary.txt && echo "✓ Text exists" || echo "✗ Text MISSING"878```879880**Required:** All three files must exist. If any are missing, regenerate them.881882#### 2. Dynamic Feature Extraction Verification883884```bash885# Verify HTML has "Tested Features (Dynamic Feature Extraction)" section886grep -q "Tested Features (Dynamic Feature Extraction)" .work/test-coverage/gaps/test-gaps-report.html && \887 echo "✓ Feature extraction section present" || \888 echo "✗ MISSING: Dynamic Feature Extraction section"889890# Verify JSON has feature data891grep -q '"tested_features"' .work/test-coverage/gaps/test-gaps-report.json && \892grep -q '"feature_gaps"' .work/test-coverage/gaps/test-gaps-report.json && \893 echo "✓ Feature data in JSON" || \894 echo "✗ MISSING: Feature data in JSON"895896# Verify Text has feature section897grep -q "Tested Features" .work/test-coverage/gaps/test-gaps-summary.txt && \898 echo "✓ Feature section in Text" || \899 echo "✗ MISSING: Feature section in Text"900```901902**Required:** Dynamic Feature Extraction must be present in all three reports. This is a critical requirement from Step 5a (lines 163-280).903904#### 3. HTML Coverage Dimension Verification905906**CRITICAL:** The HTML report must display ALL coverage dimension tables based on component type.907908```bash909# For networking components, verify ALL 8 dimension tables exist910grep -c "<h3>Platforms</h3>" .work/test-coverage/gaps/test-gaps-report.html911grep -c "<h3>Protocols</h3>" .work/test-coverage/gaps/test-gaps-report.html912grep -c "<h3>Service Types</h3>" .work/test-coverage/gaps/test-gaps-report.html913grep -c "<h3>IP Stacks</h3>" .work/test-coverage/gaps/test-gaps-report.html914grep -c "<h3>Network Layers</h3>" .work/test-coverage/gaps/test-gaps-report.html915grep -c "<h3>Gateway Modes</h3>" .work/test-coverage/gaps/test-gaps-report.html916grep -c "<h3>Topologies</h3>" .work/test-coverage/gaps/test-gaps-report.html917grep -c "<h3>Scenarios</h3>" .work/test-coverage/gaps/test-gaps-report.html918```919920**Expected Results:**921- **Networking components:** 8 dimension tables (Platforms, Protocols, Service Types, IP Stacks, Network Layers, Gateway Modes, Topologies, Scenarios)922- **Storage components:** 5 dimension tables (Platforms, Storage Classes, Volume Modes, Provisioners, Scenarios)923- **Other components:** 2 dimension tables (Platforms, Scenarios)924925**Verification Command:**926```bash927# Count total coverage dimension tables928TABLE_COUNT=$(grep -E "<h3>(Platforms|Protocols|Service Types|IP Stacks|Network Layers|Gateway Modes|Topologies|Scenarios|Storage Classes|Volume Modes|Provisioners)</h3>" .work/test-coverage/gaps/test-gaps-report.html | wc -l)929echo "Coverage dimension tables found: $TABLE_COUNT"930931# Verify based on component type932COMPONENT=$(grep -oP 'Component:</strong> \K[^<]+' .work/test-coverage/gaps/test-gaps-report.html | head -1 | tr -d '</p>')933echo "Component type: $COMPONENT"934935case "$COMPONENT" in936 Networking)937 [ "$TABLE_COUNT" -eq 8 ] && echo "✓ All 8 networking dimensions present" || echo "✗ INCOMPLETE: Expected 8 tables, found $TABLE_COUNT"938 ;;939 Storage)940 [ "$TABLE_COUNT" -eq 5 ] && echo "✓ All 5 storage dimensions present" || echo "✗ INCOMPLETE: Expected 5 tables, found $TABLE_COUNT"941 ;;942 *)943 [ "$TABLE_COUNT" -eq 2 ] && echo "✓ All 2 generic dimensions present" || echo "✗ INCOMPLETE: Expected 2 tables, found $TABLE_COUNT"944 ;;945esac946```947948**Required:** All component-specific dimension tables must be present. Missing tables indicate incomplete HTML generation.949950#### 4. Effort Estimates Verification951952```bash953# Verify gaps include effort estimates954grep -q "Effort Required" .work/test-coverage/gaps/test-gaps-report.html && \955 echo "✓ Effort estimates in HTML" || \956 echo "✗ MISSING: Effort estimates"957```958959**Required:** Gaps must include effort estimates (Low, Medium, High) as specified in Step 5a.960961#### 5. Gap Analyzer Implementation Verification962963```bash964# Verify analyzer has feature extraction function965grep -q "def extract_features_from_tests" .work/test-coverage/gaps/gap_analyzer.py && \966 echo "✓ Feature extraction function exists" || \967 echo "✗ MISSING: extract_features_from_tests() function"968969# Verify all 5 feature categories are defined970grep -q "Configuration Patterns" .work/test-coverage/gaps/gap_analyzer.py && \971grep -q "Network Topology" .work/test-coverage/gaps/gap_analyzer.py && \972grep -q "Lifecycle Operations" .work/test-coverage/gaps/gap_analyzer.py && \973grep -q "Network Features" .work/test-coverage/gaps/gap_analyzer.py && \974grep -q "Resilience & Recovery" .work/test-coverage/gaps/gap_analyzer.py && \975 echo "✓ All 5 feature categories defined" || \976 echo "✗ MISSING: Some feature categories not implemented"977```978979**Required:** The gap analyzer must implement Dynamic Feature Extraction with all 5 categories.980981#### 6. JSON Structure Verification982983```python984# Verify JSON has all required fields985python3 << 'EOF'986import json987try:988 with open('.work/test-coverage/gaps/test-gaps-report.json', 'r') as f:989 data = json.load(f)990991 required_fields = [992 ('analysis.file', lambda d: d['analysis']['file']),993 ('analysis.component_type', lambda d: d['analysis']['component_type']),994 ('analysis.test_count', lambda d: d['analysis']['test_count']),995 ('analysis.tested_features', lambda d: d['analysis']['tested_features']),996 ('analysis.feature_gaps', lambda d: d['analysis']['feature_gaps']),997 ('scores.overall', lambda d: d['scores']['overall']),998 ]9991000 missing = []1001 for name, getter in required_fields:1002 try:1003 getter(data)1004 print(f"✓ {name}")1005 except (KeyError, TypeError):1006 print(f"✗ MISSING: {name}")1007 missing.append(name)10081009 if not missing:1010 print("\n✓ All required JSON fields present")1011 else:1012 print(f"\n✗ INCOMPLETE: Missing {len(missing)} required fields")1013 exit(1)1014except Exception as e:1015 print(f"✗ ERROR: {e}")1016 exit(1)1017EOF1018```10191020**Required:** All required JSON fields must be present.10211022### Validation Summary10231024**Before declaring this skill complete:**102510261. ✓ All three report files exist10272. ✓ Dynamic Feature Extraction present in all reports10283. ✓ HTML shows ALL component-specific coverage dimension tables10294. ✓ Effort estimates included in gaps10305. ✓ Gap analyzer implements feature extraction function10316. ✓ JSON contains all required fields10321033**If ANY check fails:** Fix the issue and re-run all validation checks. Do NOT declare the skill complete until ALL checks pass.10341035## Error Handling10361037### Common Issues and Solutions103810391. **File not found**:1040 - Verify the test file path is correct1041 - Check that the file exists and is readable104210432. **Invalid file format**:1044 - Ensure the file is a Go test file (`.go`)1045 - Check that the file uses Ginkgo framework (`g.It`, `g.Describe`)104610473. **No test cases found**:1048 - Verify the file contains Ginkgo test cases1049 - Check for `g.It("...")` patterns10501051## Examples10521053### Example 1: Analyze Networking Test File10541055```bash1056# Run gap analyzer on a networking test file1057cd /home/anusaxen/git/ai-helpers/plugins/test-coverage1058python3 .work/test-coverage/gaps/gap_analyzer.py \1059 /path/to/test/extended/networking/egressip_test.go \1060 --output .work/gaps/10611062# Output:1063# Component detected: networking1064# Test cases found: 251065# Overall coverage: 45.0%1066# High-priority gaps: Azure platform, UDP protocol, Error handling scenarios1067#1068# Reports generated:1069# HTML: .work/gaps/test-gaps-report.html1070# JSON: .work/gaps/test-gaps-report.json1071# Text: .work/gaps/test-gaps-summary.txt1072```10731074### Example 2: Analyze Storage Test File10751076```bash1077# Run gap analyzer on a storage test file1078python3 .work/test-coverage/gaps/gap_analyzer.py \1079 /path/to/test/extended/storage/persistent_volumes_test.go \1080 --output .work/gaps/10811082# Output:1083# Component detected: storage1084# Test cases found: 181085# Overall coverage: 52.0%1086# High-priority gaps: ReadWriteMany volumes, CSI storage class, Snapshot scenarios1087```10881089### Example 3: Analyze from GitHub URL10901091```bash1092# Analyze file from GitHub raw URL1093python3 .work/test-cove10941095…(truncated)