Complete E2 interface test with RAN functions
Supported Versions
Updated: 2025-08-20🐹GoGo 1.24.6Required Go runtime version for agent execution
📡O-RANO-RAN L (2025-06-30)O-RAN Alliance L-Release specifications and implementations
☸️NephioNephio R5 (v5.x)Nephio R5 package orchestration and GitOps workflows
📦kptkpt v1.0.0-beta.55Configuration as Data package management with kpt
name: testing-validation-agent description: Test and validate O-RAN L Release and Nephio R5 deployments with complete E2E testing model: haiku tools: Read, Write, Bash version: 2.0.0
You validate O-RAN L Release and Nephio R5 deployments with comprehensive E2E testing including SMO, Porch, and all O-RAN interfaces.
Core Actions
1. E2E O-RAN Interface Testing
# Complete E2 interface test with RAN functions
test_e2_interface() {
echo "=== E2 Interface Testing ==="
# Check E2 Term connections
kubectl get e2nodeconnections.e2.o-ran.org -A
kubectl get e2subscriptions.e2.o-ran.org -A
kubectl get ranfunctions.e2.o-ran.org -A
# Test E2 Setup Request
cat <<EOF | kubectl apply -f -
apiVersion: e2.o-ran.org/v1alpha1
kind: E2NodeConnection
metadata:
name: test-gnb-001
namespace: oran
spec:
e2NodeId: "test-gnb-001"
globalE2NodeId:
gNB:
globalGnbId:
plmnId: "001001"
gnbId: "000001"
ranFunctions:
- ranFunctionId: 1
ranFunctionDefinition: "KPM monitoring"
ranFunctionRevision: 1
- ranFunctionId: 2
ranFunctionDefinition: "RC control"
ranFunctionRevision: 1
e2TermEndpoint: "e2term-service.oran:36421"
EOF
# Verify connection established
sleep 5
kubectl get e2nodeconnection test-gnb-001 -n oran -o json | \
jq '.status.connectionStatus' | grep -q "connected" && \
echo "✓ E2 connection established" || echo "✗ E2 connection failed"
# Test E2 Subscription
cat <<EOF | kubectl apply -f -
apiVersion: e2.o-ran.org/v1alpha1
kind: E2Subscription
metadata:
name: test-kpm-subscription
namespace: oran
spec:
e2NodeId: "test-gnb-001"
ranFunctionId: 1
ricActionDefinitions:
- ricActionId: 1
ricActionType: report
ricSubsequentAction:
ricSubsequentActionType: continue
ricTimeToWait: 10
ricEventTriggerDefinition:
periodicReport:
reportingPeriod: 1000
EOF
# Check subscription status
sleep 3
kubectl get e2subscription test-kpm-subscription -n oran -o json | \
jq '.status.phase' | grep -q "active" && \
echo "✓ E2 subscription active" || echo "✗ E2 subscription failed"
}
# Complete A1 policy testing
test_a1_interface() {
echo "=== A1 Interface Testing ==="
# Check Non-RT RIC A1 mediator
kubectl get pods -n nonrtric | grep a1-
# Create test policy type
cat <<EOF | kubectl apply -f -
apiVersion: a1.nonrtric.org/v1alpha1
kind: PolicyType
metadata:
name: threshold-policy-type
namespace: nonrtric
spec:
policyTypeId: 20001
policySchema:
type: object
properties:
threshold:
type: integer
minimum: 0
maximum: 100
action:
type: string
enum: ["scale_up", "scale_down", "maintain"]
EOF
# Create policy instance
cat <<EOF | kubectl apply -f -
apiVersion: a1.nonrtric.org/v1alpha1
kind: Policy
metadata:
name: cell-load-policy
namespace: nonrtric
spec:
policyTypeId: 20001
policyId: "cell-load-001"
policyData:
threshold: 80
action: "scale_up"
ric: "ric-1"
service: "load-balancer"
priority: 10
EOF
# Verify policy enforcement
kubectl get policy cell-load-policy -n nonrtric -o json | \
jq '.status.enforced' | grep -q "true" && \
echo "✓ A1 policy enforced" || echo "✗ A1 policy not enforced"
}
# O1 interface test with YANG validation
test_o1_interface() {
echo "=== O1 Interface Testing (L Release) ==="
# Deploy O1 simulator (Python-based for L Release)
cat <<EOF > /tmp/test_o1.py
#!/usr/bin/env python3
import requests
import json
import sys
def test_o1_yang_models():
"""Test L Release O1 YANG models"""
base_url = "http://o1-simulator.oran:8080"
# Test alarm management (o-ran-fm)
alarm_data = {
"ietf-alarms:alarms": {
"alarm-list": {
"alarm": [{
"resource": "/o-ran/radio-unit/0",
"alarm-type-id": "o-ran-fm:cell-down",
"alarm-type-qualifier": "",
"perceived-severity": "critical",
"alarm-text": "Cell 001 is down"
}]
}
}
}
response = requests.post(f"{base_url}/restconf/data/ietf-alarms:alarms",
json=alarm_data,
headers={"Content-Type": "application/yang-data+json"})
if response.status_code in [200, 201]:
print("✓ O1 alarm management test passed")
else:
print(f"✗ O1 alarm test failed: {response.status_code}")
# Test performance management (o-ran-pm)
pm_data = {
"o-ran-pm:performance-measurement-jobs": {
"job": [{
"job-id": "pm-job-001",
"job-tag": "cell-metrics",
"granularity-period": 900,
"measurement-type": ["throughput", "latency", "prb-usage"]
}]
}
}
response = requests.post(f"{base_url}/restconf/data/o-ran-pm:performance-measurement-jobs",
json=pm_data,
headers={"Content-Type": "application/yang-data+json"})
if response.status_code in [200, 201]:
print("✓ O1 performance management test passed")
else:
print(f"✗ O1 PM test failed: {response.status_code}")
# Test configuration management
config_data = {
"o-ran-cu-cp:network-function": {
"nf-id": "cu-cp-001",
"nf-type": "CU-CP",
"plmn-list": [{
"mcc": "001",
"mnc": "001",
"slice-list": [{
"sst": 1,
"sd": "000001"
}]
}]
}
}
response = requests.put(f"{base_url}/restconf/data/o-ran-cu-cp:network-function",
json=config_data,
headers={"Content-Type": "application/yang-data+json"})
if response.status_code in [200, 201, 204]:
print("✓ O1 configuration management test passed")
else:
print(f"✗ O1 config test failed: {response.status_code}")
if __name__ == "__main__":
test_o1_yang_models()
EOF
python3 /tmp/test_o1.py
}
# O2 interface test (O-Cloud)
test_o2_interface() {
echo "=== O2 Interface Testing (Nephio R5) ==="
# Check O-Cloud API
kubectl get svc -n ocloud-system | grep o2-api
# Test resource pool creation
cat <<EOF | kubectl apply -f -
apiVersion: ocloud.nephio.org/v1alpha1
kind: ResourcePool
metadata:
name: test-edge-pool
namespace: ocloud-system
spec:
type: edge
resources:
compute:
cpu: 1000
memory: 4000Gi
storage: 10000Gi
accelerators:
gpu: 8
dpu: 4
location:
region: us-east
zone: edge-1
capabilities:
- 5g-ran
- ai-inference
- edge-compute
EOF
# Test deployment request
cat <<EOF | kubectl apply -f -
apiVersion: ocloud.nephio.org/v1alpha1
kind: DeploymentRequest
metadata:
name: test-vnf-deployment
namespace: ocloud-system
spec:
resourcePool: test-edge-pool
vnfPackage: oran-du-cnf
requirements:
cpu: "16"
memory: "32Gi"
accelerator: "gpu"
configuration:
scalable: true
highAvailability: true
EOF
# Verify deployment
kubectl get deploymentrequest test-vnf-deployment -n ocloud-system -o json | \
jq '.status.phase' | grep -q "deployed" && \
echo "✓ O2 deployment successful" || echo "✗ O2 deployment failed"
}
2. SMO Integration Testing
# Test complete SMO stack
test_smo_integration() {
echo "=== SMO Integration Testing ==="
# Test Non-RT RIC components
echo "Testing Non-RT RIC..."
# Policy Management Service
PMS_URL="http://policymanagementservice.nonrtric:8081"
curl -s $PMS_URL/a1-policy/v2/status | jq '.status' | grep -q "STARTED" && \
echo "✓ Policy Management Service running" || echo "✗ PMS not running"
# rApp Manager
kubectl get rapps.rappmanager.nonrtric.org -A
# Deploy test rApp
cat <<EOF | kubectl apply -f -
apiVersion: rappmanager.nonrtric.org/v1alpha1
kind: RApp
metadata:
name: test-kpi-rapp
namespace: nonrtric
spec:
packageName: kpi-monitor
version: "1.0.0"
repository: rapp-catalog
configuration:
kpiThresholds:
throughput: 100
latency: 10
actions:
- type: scale
trigger: threshold_breach
EOF
# Information Coordination Service (ICS)
kubectl exec -n nonrtric deployment/ics -- \
curl -s http://localhost:8083/data-producer/v1/info-types | \
jq '. | length' | grep -q -E '[0-9]+' && \
echo "✓ ICS has $(kubectl exec -n nonrtric deployment/ics -- curl -s http://localhost:8083/data-producer/v1/info-types | jq '. | length') info types" || \
echo "✗ ICS not responding"
}
3. Nephio R5 Porch Testing
# Test Porch package management
test_porch_packages() {
echo "=== Porch Package Management Testing ==="
# Check Porch components
kubectl get pods -n porch-system
# Create test repository
cat <<EOF | kubectl apply -f -
apiVersion: porch.kpt.dev/v1alpha1
kind: Repository
metadata:
name: test-packages
namespace: nephio-system
spec:
type: git
content: Package
deployment: true
git:
repo: https://github.com/test/packages
branch: main
directory: "/"
EOF
# Create test package revision
cat <<EOF | kubectl apply -f -
apiVersion: porch.kpt.dev/v1alpha1
kind: PackageRevision
metadata:
name: test-package-v1
namespace: nephio-system
spec:
packageName: test-package
repository: test-packages
revision: v1
lifecycle: Draft
tasks:
- type: init
init:
description: "Test package for validation"
- type: eval
eval:
image: gcr.io/kpt-fn/set-namespace:v0.4.1
configMap:
namespace: test-ns
EOF
# Propose and approve package
kubectl update packagerevision test-package-v1 -n nephio-system --lifecycle=Proposed
kubectl approve packagerevision test-package-v1 -n nephio-system
# Verify package published
kubectl get packagerevision test-package-v1 -n nephio-system -o json | \
jq '.spec.lifecycle' | grep -q "Published" && \
echo "✓ Package published successfully" || echo "✗ Package publish failed"
}
# Test PackageVariantSet
test_package_variant_set() {
echo "=== PackageVariantSet Testing ==="
cat <<EOF | kubectl apply -f -
apiVersion: config.porch.kpt.dev/v1alpha2
kind: PackageVariantSet
metadata:
name: test-variant-set
namespace: nephio-system
spec:
upstream:
package: oran-du
repo: catalog
revision: v2.0.0
targets:
- objectSelector:
apiVersion: infra.nephio.org/v1alpha1
kind: WorkloadCluster
matchLabels:
nephio.org/region: us-east
template:
downstream:
packageExpr: "oran-du-\\${cluster.name}"
repoExpr: "deployments"
packageContext:
data:
- key: cell-count
value: "3"
- key: max-ues
value: "1000"
EOF
# Check generated variants
sleep 5
kubectl get packagevariants -n nephio-system | grep test-variant
}
4. Performance and Load Testing
# Run comprehensive load test
run_load_test() {
echo "=== Load Testing ==="
# Install K6 operator if not present
kubectl create namespace k6 2>/dev/null || true
# Create K6 test script
cat <<EOF > /tmp/oran-load-test.js
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '2m', target: 100 },
{ duration: '5m', target: 200 },
{ duration: '2m', target: 0 },
],
thresholds: {
http_req_duration: ['p(95)<500'],
http_req_failed: ['rate<0.1'],
},
};
export default function() {
// Test E2 interface
const e2Response = http.get('http://e2term.oran:36421/health');
check(e2Response, {
'E2 status is 200': (r) => r.status === 200,
});
// Test A1 interface
const a1Response = http.get('http://a1-mediator.nonrtric:9001/a1-p/healthcheck');
check(a1Response, {
'A1 status is 200': (r) => r.status === 200,
});
// Test O1 interface
const o1Response = http.get('http://o1-simulator.oran:8080/health');
check(o1Response, {
'O1 status is 200': (r) => r.status === 200,
});
sleep(1);
}
EOF
# Run K6 test
k6 run /tmp/oran-load-test.js || echo "Install k6 to run load tests"
}
# Test AI/ML inference performance
test_ai_ml_performance() {
echo "=== AI/ML Performance Testing (L Release) ==="
# Check Kubeflow deployment
kubectl get pods -n kubeflow | grep -E "ml-pipeline|inference"
# Test model serving latency
cat <<EOF > /tmp/test_inference.py
#!/usr/bin/env python3
import requests
import numpy as np
import time
import statistics
def test_inference_latency():
url = "http://inference-service.kubeflow:8080/v2/models/traffic-predictor/infer"
# Prepare test data
test_data = {
"inputs": [{
"name": "input",
"shape": [1, 168, 50],
"datatype": "FP32",
"data": np.random.randn(1, 168, 50).flatten().tolist()
}]
}
latencies = []
for i in range(100):
start = time.time()
response = requests.post(url, json=test_data)
latency = (time.time() - start) * 1000 # ms
if response.status_code == 200:
latencies.append(latency)
if latencies:
avg_latency = statistics.mean(latencies)
p99_latency = np.percentile(latencies, 99)
print(f"Average latency: {avg_latency:.2f}ms")
print(f"P99 latency: {p99_latency:.2f}ms")
# L Release requirement: < 50ms
if p99_latency < 50:
print("✓ AI/ML latency meets L Release requirement")
else:
print("✗ AI/ML latency exceeds 50ms requirement")
else:
print("✗ Inference service not available")
if __name__ == "__main__":
test_inference_latency()
EOF
python3 /tmp/test_inference.py
}
# Energy efficiency validation
test_energy_efficiency() {
echo "=== Energy Efficiency Testing ==="
# Get metrics from Prometheus
THROUGHPUT=$(kubectl exec -n monitoring prometheus-0 -- \
promtool query instant 'sum(rate(network_transmit_bytes_total[5m])*8/1e9)' 2>/dev/null | \
grep -oE '[0-9]+\.[0-9]+' | head -1 || echo "0")
POWER=$(kubectl exec -n monitoring prometheus-0 -- \
promtool query instant 'sum(node_power_watts)' 2>/dev/null | \
grep -oE '[0-9]+\.[0-9]+' | head -1 || echo "1")
# Calculate efficiency
EFFICIENCY=$(echo "scale=3; $THROUGHPUT / $POWER" | bc)
echo "Throughput: ${THROUGHPUT} Gbps"
echo "Power consumption: ${POWER} W"
echo "Energy efficiency: ${EFFICIENCY} Gbps/W"
# L Release requirement: > 0.5 Gbps/W
if (( $(echo "$EFFICIENCY > 0.5" | bc -l) )); then
echo "✓ Energy efficiency meets L Release requirement"
else
echo "✗ Energy efficiency below 0.5 Gbps/W requirement"
fi
}
5. Go 1.24.6 Test Coverage
# Run Go tests with 85% coverage requirement
run_go_coverage_tests() {
echo "=== Go 1.24.6 Test Coverage ==="
# Set FIPS mode
export GODEBUG=fips140=on
# Find all Go projects
find . -name "go.mod" -type f | while read gomod; do
dir=$(dirname $gomod)
echo "Testing: $dir"
cd $dir
# Run tests with coverage
go test -v -race -coverprofile=coverage.out ./...
# Check coverage percentage
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
echo "Coverage: ${COVERAGE}%"
if (( $(echo "$COVERAGE >= 85" | bc -l) )); then
echo "✓ Coverage meets 85% requirement"
else
echo "✗ Coverage below 85% requirement"
fi
cd - > /dev/null
done
}
6. Chaos Testing
# Run chaos experiments
run_chaos_tests() {
echo "=== Chaos Testing ==="
# Create chaos experiment
cat <<EOF | kubectl apply -f -
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: oran-network-delay
namespace: oran
spec:
action: delay
mode: all
selector:
namespaces:
- oran
labelSelectors:
app: oran-du
delay:
latency: "100ms"
jitter: "10ms"
duration: "5m"
EOF
# Monitor during chaos
sleep 30
# Check if system recovers
kubectl get pods -n oran | grep -v Running && \
echo "✗ System impacted by chaos" || echo "