| Eric Ball | 6f17fcb | 2026-03-04 18:00:51 -0800 | [diff] [blame] | 1 | --- |
| 2 | # SPDX-License-Identifier: Apache-2.0 |
| 3 | # SPDX-FileCopyrightText: 2026 Open Networking Foundation Contributors |
| 4 | |
| 5 | name: "bbsim-tests" |
| 6 | description: "VOLTHA BBSim E2E Tests - Simulates OLT/ONUs using bbsim and runs robot framework tests" |
| 7 | |
| 8 | inputs: |
| 9 | branch: |
| 10 | description: "Branch to test (master, voltha-2.15, etc.)" |
| 11 | required: true |
| Eric Ball | 6f17fcb | 2026-03-04 18:00:51 -0800 | [diff] [blame] | 12 | test-targets: |
| 13 | description: "YAML string defining test targets to run" |
| 14 | required: true |
| Eric Ball | 6f17fcb | 2026-03-04 18:00:51 -0800 | [diff] [blame] | 15 | gerrit-project: |
| 16 | description: "Gerrit project name if building a patch" |
| 17 | required: false |
| Eric Ball | 6f17fcb | 2026-03-04 18:00:51 -0800 | [diff] [blame] | 18 | default: "" |
| 19 | gerrit-refspec: |
| 20 | description: "Gerrit refspec if building a patch" |
| 21 | required: false |
| Eric Ball | 6f17fcb | 2026-03-04 18:00:51 -0800 | [diff] [blame] | 22 | default: "" |
| 23 | extra-helm-flags: |
| 24 | description: "Additional Helm flags for deployment" |
| 25 | required: false |
| Eric Ball | 6f17fcb | 2026-03-04 18:00:51 -0800 | [diff] [blame] | 26 | default: "" |
| 27 | log-level: |
| 28 | description: "Log level for VOLTHA components (DEBUG, INFO, WARN, ERROR)" |
| 29 | required: false |
| Eric Ball | 6f17fcb | 2026-03-04 18:00:51 -0800 | [diff] [blame] | 30 | default: "WARN" |
| 31 | timeout: |
| 32 | description: "Timeout in minutes for the entire action" |
| 33 | required: false |
| Eric Ball | 6f17fcb | 2026-03-04 18:00:51 -0800 | [diff] [blame] | 34 | default: "240" |
| 35 | cluster-name: |
| 36 | description: "Name of the kind cluster" |
| 37 | required: false |
| Eric Ball | 6f17fcb | 2026-03-04 18:00:51 -0800 | [diff] [blame] | 38 | default: "kind-ci" |
| 39 | docker-registry: |
| 40 | description: "Docker registry to use" |
| 41 | required: false |
| Eric Ball | 6f17fcb | 2026-03-04 18:00:51 -0800 | [diff] [blame] | 42 | default: "linuxfoundation.jfrog.io/voltha-docker" |
| 43 | olts: |
| 44 | description: "Number of OLTs to simulate" |
| 45 | required: false |
| Eric Ball | 6f17fcb | 2026-03-04 18:00:51 -0800 | [diff] [blame] | 46 | default: "1" |
| 47 | with-monitoring: |
| 48 | description: "Enable monitoring with prometheus" |
| 49 | required: false |
| Eric Ball | 96e7f8f | 2026-06-26 16:56:18 -0700 | [diff] [blame] | 50 | default: "false" |
| Eric Ball | 6f17fcb | 2026-03-04 18:00:51 -0800 | [diff] [blame] | 51 | enable-mac-learning: |
| 52 | description: "Enable MAC learning in VOLTHA" |
| 53 | required: false |
| Eric Ball | 96e7f8f | 2026-06-26 16:56:18 -0700 | [diff] [blame] | 54 | default: "false" |
| Eric Ball | 6f17fcb | 2026-03-04 18:00:51 -0800 | [diff] [blame] | 55 | extra-robot-args: |
| 56 | description: "Additional arguments for Robot Framework" |
| 57 | required: false |
| Eric Ball | 6f17fcb | 2026-03-04 18:00:51 -0800 | [diff] [blame] | 58 | default: "" |
| 59 | |
| 60 | outputs: |
| 61 | test-results: |
| 62 | description: "Path to test results" |
| 63 | value: ${{ steps.test-execution.outputs.results-path }} |
| 64 | |
| 65 | runs: |
| 66 | using: "composite" |
| 67 | steps: |
| 68 | # ----------------------------------------------------------------------- |
| 69 | # Setup environment variables |
| 70 | # ----------------------------------------------------------------------- |
| 71 | - name: Setup environment |
| 72 | shell: bash |
| 73 | run: | |
| 74 | echo "KUBECONFIG=$HOME/.kube/kind-${{ inputs.cluster-name }}" >> $GITHUB_ENV |
| 75 | echo "VOLTCONFIG=$HOME/.volt/config" >> $GITHUB_ENV |
| 76 | echo "PATH=$PATH:$GITHUB_WORKSPACE/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" >> $GITHUB_ENV |
| 77 | echo "DIAGS_PROFILE=VOLTHA_PROFILE" >> $GITHUB_ENV |
| 78 | echo "SSHPASS=karaf" >> $GITHUB_ENV |
| 79 | mkdir -p $GITHUB_WORKSPACE/bin |
| 80 | |
| 81 | # ----------------------------------------------------------------------- |
| 82 | # Install dependencies |
| 83 | # ----------------------------------------------------------------------- |
| 84 | - name: Install system dependencies |
| 85 | shell: bash |
| 86 | run: | |
| 87 | echo "Installing system dependencies..." |
| 88 | sudo apt-get update |
| 89 | sudo apt-get install -y \ |
| 90 | curl \ |
| 91 | wget \ |
| 92 | git \ |
| 93 | make \ |
| 94 | jq \ |
| 95 | sshpass \ |
| 96 | python3 \ |
| 97 | python3-pip \ |
| 98 | python3-venv \ |
| 99 | rsync |
| 100 | |
| 101 | # ----------------------------------------------------------------------- |
| 102 | # Install kubectl |
| 103 | # ----------------------------------------------------------------------- |
| 104 | - name: Install kubectl |
| 105 | shell: bash |
| 106 | run: | |
| 107 | echo "Installing kubectl..." |
| 108 | if [ ! -f "$GITHUB_WORKSPACE/bin/kubectl" ]; then |
| 109 | KUBECTL_VERSION=$(curl -L -s https://dl.k8s.io/release/stable.txt) |
| 110 | curl -Lo "$GITHUB_WORKSPACE/bin/kubectl" \ |
| 111 | "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl" |
| 112 | chmod +x "$GITHUB_WORKSPACE/bin/kubectl" |
| 113 | fi |
| 114 | kubectl version --client |
| 115 | |
| 116 | # ----------------------------------------------------------------------- |
| 117 | # Install Helm |
| 118 | # ----------------------------------------------------------------------- |
| 119 | - name: Install Helm |
| 120 | shell: bash |
| 121 | run: | |
| 122 | echo "Installing Helm..." |
| 123 | if ! command -v helm &> /dev/null; then |
| 124 | curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash |
| 125 | fi |
| 126 | helm version |
| 127 | |
| 128 | # ----------------------------------------------------------------------- |
| 129 | # Install kind |
| 130 | # ----------------------------------------------------------------------- |
| 131 | - name: Install kind |
| 132 | shell: bash |
| 133 | run: | |
| 134 | echo "Installing kind..." |
| 135 | if [ ! -f "$GITHUB_WORKSPACE/bin/kind" ]; then |
| 136 | KIND_VERSION="v0.20.0" |
| 137 | curl -Lo "$GITHUB_WORKSPACE/bin/kind" \ |
| 138 | "https://kind.sigs.k8s.io/dl/${KIND_VERSION}/kind-linux-amd64" |
| 139 | chmod +x "$GITHUB_WORKSPACE/bin/kind" |
| 140 | fi |
| 141 | kind version |
| 142 | |
| 143 | # ----------------------------------------------------------------------- |
| 144 | # Install kail |
| 145 | # ----------------------------------------------------------------------- |
| 146 | - name: Install kail |
| 147 | shell: bash |
| 148 | run: | |
| 149 | echo "Installing kail..." |
| 150 | if [ ! -f "$GITHUB_WORKSPACE/bin/kail" ]; then |
| 151 | KAIL_VERSION="v0.17.4" |
| 152 | wget -O /tmp/kail.tar.gz \ |
| 153 | "https://github.com/boz/kail/releases/download/${KAIL_VERSION}/kail_${KAIL_VERSION}_linux_amd64.tar.gz" |
| 154 | tar -xzf /tmp/kail.tar.gz -C "$GITHUB_WORKSPACE/bin" kail |
| 155 | chmod +x "$GITHUB_WORKSPACE/bin/kail" |
| 156 | rm /tmp/kail.tar.gz |
| 157 | fi |
| 158 | |
| 159 | # ----------------------------------------------------------------------- |
| 160 | # Install voltctl |
| 161 | # ----------------------------------------------------------------------- |
| 162 | - name: Install voltctl |
| 163 | shell: bash |
| 164 | run: | |
| 165 | echo "Installing voltctl..." |
| 166 | if [ "${{ inputs.gerrit-project }}" != "voltctl" ]; then |
| 167 | if [ ! -f "$GITHUB_WORKSPACE/bin/voltctl" ]; then |
| 168 | VOLTCTL_VERSION="1.8.45" |
| 169 | curl -Lo "$GITHUB_WORKSPACE/bin/voltctl" \ |
| 170 | "https://github.com/opencord/voltctl/releases/download/v${VOLTCTL_VERSION}/voltctl-${VOLTCTL_VERSION}-linux-amd64" |
| 171 | chmod +x "$GITHUB_WORKSPACE/bin/voltctl" |
| 172 | fi |
| 173 | fi |
| 174 | |
| 175 | # ----------------------------------------------------------------------- |
| 176 | # Checkout VOLTHA repositories |
| 177 | # ----------------------------------------------------------------------- |
| 178 | - name: Checkout voltha-system-tests |
| 179 | uses: actions/checkout@v4 |
| 180 | with: |
| 181 | repository: opencord/voltha-system-tests |
| 182 | ref: ${{ inputs.branch }} |
| 183 | path: voltha-system-tests |
| 184 | |
| Eric Ball | 6f17fcb | 2026-03-04 18:00:51 -0800 | [diff] [blame] | 185 | - name: Checkout voltha-helm-charts |
| 186 | uses: actions/checkout@v4 |
| 187 | with: |
| 188 | repository: opencord/voltha-helm-charts |
| 189 | ref: ${{ inputs.branch }} |
| 190 | path: voltha-helm-charts |
| 191 | |
| Eric Ball | 6f17fcb | 2026-03-04 18:00:51 -0800 | [diff] [blame] | 192 | # ----------------------------------------------------------------------- |
| 193 | # Checkout and build gerrit project if specified |
| 194 | # ----------------------------------------------------------------------- |
| 195 | - name: Checkout gerrit project |
| 196 | if: inputs.gerrit-project != '' |
| 197 | uses: actions/checkout@v4 |
| 198 | with: |
| 199 | repository: opencord/${{ inputs.gerrit-project }} |
| 200 | ref: ${{ inputs.gerrit-refspec }} |
| 201 | path: ${{ inputs.gerrit-project }} |
| 202 | |
| 203 | - name: Build gerrit project |
| 204 | if: inputs.gerrit-project != '' |
| 205 | shell: bash |
| 206 | working-directory: ${{ inputs.gerrit-project }} |
| 207 | run: | |
| 208 | echo "Building ${{ inputs.gerrit-project }}..." |
| 209 | if [ -f "Makefile" ]; then |
| 210 | make docker-build |
| 211 | fi |
| 212 | |
| 213 | - name: Build and install voltctl from source |
| 214 | if: inputs.gerrit-project == 'voltctl' |
| 215 | shell: bash |
| 216 | working-directory: voltctl |
| 217 | run: | |
| 218 | echo "Building voltctl from source..." |
| 219 | make build |
| 220 | cp voltctl "$GITHUB_WORKSPACE/bin/" |
| 221 | chmod +x "$GITHUB_WORKSPACE/bin/voltctl" |
| 222 | |
| 223 | # ----------------------------------------------------------------------- |
| 224 | # Create kind cluster |
| 225 | # ----------------------------------------------------------------------- |
| 226 | - name: Check if kind cluster exists |
| 227 | id: cluster-check |
| 228 | shell: bash |
| 229 | run: | |
| 230 | if kind get clusters | grep -q "^${{ inputs.cluster-name }}$"; then |
| 231 | echo "exists=true" >> $GITHUB_OUTPUT |
| 232 | else |
| 233 | echo "exists=false" >> $GITHUB_OUTPUT |
| 234 | fi |
| 235 | |
| 236 | - name: Create kind cluster |
| 237 | if: steps.cluster-check.outputs.exists == 'false' |
| 238 | shell: bash |
| 239 | run: | |
| 240 | echo "Creating kind cluster ${{ inputs.cluster-name }}..." |
| 241 | cat <<EOF > /tmp/kind-config.yaml |
| 242 | kind: Cluster |
| 243 | apiVersion: kind.x-k8s.io/v1alpha4 |
| 244 | nodes: |
| 245 | - role: control-plane |
| 246 | - role: worker |
| 247 | - role: worker |
| 248 | EOF |
| 249 | |
| 250 | kind create cluster --name ${{ inputs.cluster-name }} --config /tmp/kind-config.yaml |
| 251 | |
| 252 | # Configure kubeconfig |
| 253 | mkdir -p $HOME/.kube |
| 254 | kind export kubeconfig --name ${{ inputs.cluster-name }} --kubeconfig $HOME/.kube/kind-${{ inputs.cluster-name }} |
| 255 | |
| 256 | # Wait for cluster to be ready |
| 257 | kubectl wait --for=condition=Ready nodes --all --timeout=300s |
| 258 | |
| 259 | # ----------------------------------------------------------------------- |
| 260 | # Load images to kind if building a component |
| 261 | # ----------------------------------------------------------------------- |
| 262 | - name: Load images to kind |
| 263 | if: inputs.gerrit-project != '' && inputs.gerrit-project != 'voltctl' |
| 264 | shell: bash |
| 265 | run: | |
| 266 | echo "Loading images to kind cluster..." |
| 267 | PROJECT="${{ inputs.gerrit-project }}" |
| 268 | IMAGE_NAME="${PROJECT//-/_}" |
| 269 | |
| 270 | # Find the built image |
| 271 | IMAGE=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep -E "voltha/${PROJECT}|opencord/${PROJECT}" | head -1) |
| 272 | |
| 273 | if [ -n "$IMAGE" ]; then |
| 274 | echo "Loading image: $IMAGE" |
| 275 | kind load docker-image "$IMAGE" --name ${{ inputs.cluster-name }} |
| 276 | else |
| 277 | echo "Warning: No image found for project $PROJECT" |
| 278 | fi |
| 279 | |
| 280 | # ----------------------------------------------------------------------- |
| 281 | # Setup Helm repositories |
| 282 | # ----------------------------------------------------------------------- |
| 283 | - name: Setup Helm repositories |
| 284 | shell: bash |
| 285 | run: | |
| 286 | echo "Adding Helm repositories..." |
| 287 | helm repo add onf https://charts.lfbroadband.org |
| 288 | helm repo add cord https://charts.lfbroadband.org |
| 289 | helm repo update |
| 290 | |
| 291 | # ----------------------------------------------------------------------- |
| 292 | # Run tests |
| 293 | # ----------------------------------------------------------------------- |
| 294 | - name: Install PyYAML for test parsing |
| 295 | shell: bash |
| 296 | run: | |
| 297 | pip3 install pyyaml |
| 298 | |
| 299 | - name: Create test execution script |
| 300 | shell: bash |
| 301 | run: | |
| 302 | # Create the test execution script inline |
| 303 | cat > /tmp/execute_test.sh <<'EXECUTE_TEST_SCRIPT' |
| 304 | #!/bin/bash |
| 305 | set -euo pipefail |
| 306 | |
| 307 | # Get environment variables |
| 308 | TEST_TARGET="${TEST_TARGET:-functional-single-kind-dt}" |
| 309 | WORKFLOW="${WORKFLOW:-dt}" |
| 310 | TEST_FLAGS="${TEST_FLAGS:-}" |
| 311 | TEARDOWN="${TEARDOWN:-true}" |
| 312 | TEST_LOGGING="${TEST_LOGGING:-True}" |
| 313 | VGC_ENABLED="${VGC_ENABLED:-false}" |
| 314 | INFRA_NAMESPACE="${INFRA_NAMESPACE:-default}" |
| 315 | VOLTHA_NAMESPACE="${VOLTHA_NAMESPACE:-voltha}" |
| 316 | LOGS_DIR="${LOGS_DIR:-$GITHUB_WORKSPACE/logs}" |
| 317 | EXTRA_HELM_FLAGS="${EXTRA_HELM_FLAGS:-}" |
| 318 | LOG_LEVEL="${LOG_LEVEL:-WARN}" |
| 319 | DOCKER_REGISTRY="${DOCKER_REGISTRY:-linuxfoundation.jfrog.io/voltha-docker}" |
| 320 | OLTS="${OLTS:-1}" |
| 321 | WITH_MONITORING="${WITH_MONITORING:-false}" |
| 322 | ENABLE_MAC_LEARNING="${ENABLE_MAC_LEARNING:-false}" |
| 323 | EXTRA_ROBOT_ARGS="${EXTRA_ROBOT_ARGS:-}" |
| 324 | BRANCH="${BRANCH:-master}" |
| 325 | GERRIT_PROJECT="${GERRIT_PROJECT:-}" |
| 326 | |
| 327 | # Helper functions |
| 328 | banner() { |
| 329 | echo "" |
| 330 | echo "** -----------------------------------------------------------------------" |
| 331 | echo "** $1" |
| 332 | echo "** -----------------------------------------------------------------------" |
| 333 | echo "" |
| 334 | } |
| 335 | |
| 336 | cleanup_port_forward() { |
| 337 | echo "Cleaning up port-forward processes..." |
| 338 | pkill -f "kubectl.*port-forward" || true |
| 339 | } |
| 340 | |
| 341 | get_pods_info() { |
| 342 | local logs_dir=$1 |
| 343 | mkdir -p "$logs_dir" |
| 344 | kubectl get pods --all-namespaces -o wide > "$logs_dir/pods.txt" || true |
| 345 | kubectl get nodes -o wide > "$logs_dir/nodes.txt" || true |
| 346 | kubectl describe pods -n "$VOLTHA_NAMESPACE" > "$logs_dir/voltha-pods-describe.txt" || true |
| 347 | kubectl describe pods -n "$INFRA_NAMESPACE" > "$logs_dir/infra-pods-describe.txt" || true |
| 348 | } |
| 349 | |
| 350 | # Stage: Cleanup (if teardown enabled) |
| 351 | if [ "$TEARDOWN" = "true" ]; then |
| 352 | banner "Cleanup - Helm Teardown" |
| 353 | cleanup_port_forward |
| 354 | for namespace in default "$INFRA_NAMESPACE" "$VOLTHA_NAMESPACE"; do |
| 355 | echo "Cleaning up Helm releases in namespace: $namespace" |
| 356 | helm list -n "$namespace" -q | xargs -r helm uninstall -n "$namespace" || true |
| 357 | done |
| 358 | echo "Waiting for pods to terminate..." |
| 359 | kubectl wait --for=delete pods --all -n "$VOLTHA_NAMESPACE" --timeout=120s || true |
| 360 | kubectl wait --for=delete pods --all -n "$INFRA_NAMESPACE" --timeout=120s || true |
| 361 | fi |
| 362 | |
| 363 | # Stage: Deploy Common Infrastructure |
| 364 | banner "Deploying Common Infrastructure" |
| 365 | if [ "$WITH_MONITORING" = "true" ]; then |
| 366 | echo "Deploying monitoring stack..." |
| 367 | helm install nem-monitoring onf/nem-monitoring \ |
| 368 | --set prometheus.alertmanager.enabled=false \ |
| 369 | --set prometheus.pushgateway.enabled=false \ |
| 370 | --set kpi_exporter.enabled=false \ |
| 371 | --set dashboards.xos=false \ |
| 372 | --set dashboards.onos=false \ |
| 373 | --set dashboards.aaa=false \ |
| 374 | --set dashboards.voltha=false \ |
| 375 | --wait || true |
| 376 | fi |
| 377 | |
| 378 | # Stage: Deploy VOLTHA |
| 379 | if [ "$TEARDOWN" = "true" ]; then |
| 380 | banner "Deploying VOLTHA" |
| 381 | ONOS_LOG="${LOGS_DIR}/onos-voltha-startup-combined.log" |
| 382 | mkdir -p "$LOGS_DIR" |
| 383 | touch "$ONOS_LOG" |
| 384 | _TAG=kail-startup kail -n "${INFRA_NAMESPACE}" -n "${VOLTHA_NAMESPACE}" > "$ONOS_LOG" & |
| 385 | KAIL_PID=$! |
| 386 | |
| 387 | LOCAL_CHARTS="false" |
| 388 | if [ -d "$GITHUB_WORKSPACE/voltha-helm-charts" ]; then |
| 389 | LOCAL_CHARTS="true" |
| 390 | fi |
| 391 | |
| 392 | HELM_FLAGS="--set global.log_level=${LOG_LEVEL^^}" |
| 393 | if [ "$VGC_ENABLED" != "true" ]; then |
| 394 | HELM_FLAGS="$HELM_FLAGS --set onos-classic.onosSshPort=30115" |
| 395 | HELM_FLAGS="$HELM_FLAGS --set onos-classic.onosApiPort=30120" |
| 396 | HELM_FLAGS="$HELM_FLAGS --set onos-classic.onosOfPort=31653" |
| 397 | HELM_FLAGS="$HELM_FLAGS --set onos-classic.individualOpenFlowNodePorts=true" |
| 398 | fi |
| 399 | if [ -n "$EXTRA_HELM_FLAGS" ]; then |
| 400 | HELM_FLAGS="$HELM_FLAGS $EXTRA_HELM_FLAGS" |
| 401 | fi |
| 402 | if [ -n "$TEST_FLAGS" ]; then |
| 403 | HELM_FLAGS="$HELM_FLAGS $TEST_FLAGS" |
| 404 | fi |
| 405 | |
| 406 | if [ -n "$GERRIT_PROJECT" ] && [ "$GERRIT_PROJECT" != "voltctl" ]; then |
| 407 | IMAGE_TAG="citest" |
| 408 | case "$GERRIT_PROJECT" in |
| 409 | voltha-go) |
| 410 | HELM_FLAGS="$HELM_FLAGS --set voltha.image.tag=$IMAGE_TAG" |
| 411 | ;; |
| 412 | voltha-openolt-adapter) |
| 413 | HELM_FLAGS="$HELM_FLAGS --set voltha-adapter-openolt.image.tag=$IMAGE_TAG" |
| 414 | ;; |
| 415 | voltha-openonu-adapter-go) |
| 416 | HELM_FLAGS="$HELM_FLAGS --set voltha-adapter-openonu.image.tag=$IMAGE_TAG" |
| 417 | ;; |
| 418 | ofagent-go) |
| 419 | HELM_FLAGS="$HELM_FLAGS --set voltha.ofagent.image.tag=$IMAGE_TAG" |
| 420 | ;; |
| 421 | bbsim) |
| 422 | HELM_FLAGS="$HELM_FLAGS --set bbsim.image.tag=$IMAGE_TAG" |
| 423 | ;; |
| 424 | esac |
| 425 | fi |
| 426 | |
| 427 | echo "Deploying VOLTHA with workflow: $WORKFLOW" |
| 428 | echo "Helm flags: $HELM_FLAGS" |
| 429 | |
| 430 | if [ "$LOCAL_CHARTS" = "true" ]; then |
| 431 | echo "Using local charts from $GITHUB_WORKSPACE/voltha-helm-charts" |
| 432 | helm dependency update "$GITHUB_WORKSPACE/voltha-helm-charts/voltha-infra" || true |
| 433 | helm dependency update "$GITHUB_WORKSPACE/voltha-helm-charts/voltha-stack" || true |
| 434 | helm install voltha-infra "$GITHUB_WORKSPACE/voltha-helm-charts/voltha-infra" \ |
| 435 | -n "$INFRA_NAMESPACE" --create-namespace --wait --timeout 120m |
| 436 | helm install voltha "$GITHUB_WORKSPACE/voltha-helm-charts/voltha-stack" \ |
| 437 | -n "$VOLTHA_NAMESPACE" --create-namespace \ |
| 438 | --set global.stack_name=voltha \ |
| 439 | --set global.voltha_infra_name=voltha-infra \ |
| 440 | --set global.voltha_infra_namespace="$INFRA_NAMESPACE" \ |
| 441 | $(echo "$HELM_FLAGS") --wait --timeout 120m |
| 442 | else |
| 443 | echo "Using charts from Helm repository" |
| 444 | helm install voltha-infra onf/voltha-infra \ |
| 445 | -n "$INFRA_NAMESPACE" --create-namespace --wait --timeout 120m |
| 446 | helm install voltha onf/voltha-stack \ |
| 447 | -n "$VOLTHA_NAMESPACE" --create-namespace \ |
| 448 | --set global.stack_name=voltha \ |
| 449 | --set global.voltha_infra_name=voltha-infra \ |
| 450 | --set global.voltha_infra_namespace="$INFRA_NAMESPACE" \ |
| 451 | $(echo "$HELM_FLAGS") --wait --timeout 120m |
| 452 | fi |
| 453 | |
| 454 | for i in $(seq 0 $((OLTS - 1))); do |
| 455 | echo "Deploying bbsim${i}..." |
| 456 | if [ "$LOCAL_CHARTS" = "true" ]; then |
| 457 | helm install "bbsim${i}" "$GITHUB_WORKSPACE/voltha-helm-charts/bbsim" \ |
| 458 | -n "$VOLTHA_NAMESPACE" --set olt_id="${i}" --wait || true |
| 459 | else |
| 460 | helm install "bbsim${i}" onf/bbsim \ |
| 461 | -n "$VOLTHA_NAMESPACE" --set olt_id="${i}" --wait || true |
| 462 | fi |
| 463 | done |
| 464 | |
| 465 | if [ -n "${KAIL_PID:-}" ]; then |
| 466 | kill "$KAIL_PID" || true |
| 467 | wait "$KAIL_PID" 2>/dev/null || true |
| 468 | fi |
| 469 | gzip -f "$ONOS_LOG" || true |
| 470 | |
| 471 | echo "Setting up port forwarding..." |
| 472 | kubectl port-forward --address 0.0.0.0 -n "$INFRA_NAMESPACE" svc/voltha-infra-kafka 9092:9092 & |
| 473 | bbsim_dmi_port=50075 |
| 474 | for i in $(seq 0 $((OLTS - 1))); do |
| 475 | kubectl port-forward --address 0.0.0.0 -n "$VOLTHA_NAMESPACE" "svc/bbsim${i}" "${bbsim_dmi_port}:50075" & |
| 476 | ((bbsim_dmi_port++)) |
| 477 | done |
| 478 | if [ "$WITH_MONITORING" = "true" ]; then |
| 479 | kubectl port-forward --address 0.0.0.0 -n default svc/nem-monitoring-prometheus-server 31301:80 & |
| 480 | fi |
| 481 | if [ "$VGC_ENABLED" = "true" ]; then |
| 482 | kubectl port-forward --address 0.0.0.0 -n "$VOLTHA_NAMESPACE" svc/voltha-voltha-go-controller 8181:8181 & |
| 483 | fi |
| 484 | sleep 5 |
| 485 | fi |
| 486 | |
| 487 | # Stage: Run Tests |
| 488 | banner "Running test ${TEST_TARGET} on workflow ${WORKFLOW}" |
| 489 | if [ "$WITH_MONITORING" = "true" ]; then |
| 490 | echo "Collecting initial memory consumption..." |
| 491 | mkdir -p "$GITHUB_WORKSPACE/voltha-pods-mem-consumption-${WORKFLOW}" |
| 492 | cd "$GITHUB_WORKSPACE/voltha-system-tests" |
| 493 | if [ -f "requirements.txt" ]; then |
| 494 | python3 -m venv .venv || true |
| 495 | source .venv/bin/activate || true |
| 496 | pip install -r requirements.txt || true |
| 497 | if [ -f "scripts/mem_consumption.py" ]; then |
| 498 | python scripts/mem_consumption.py \ |
| 499 | -o "$GITHUB_WORKSPACE/voltha-pods-mem-consumption-${WORKFLOW}" \ |
| 500 | -a 0.0.0.0:31301 -n "$VOLTHA_NAMESPACE" || true |
| 501 | fi |
| 502 | fi |
| 503 | fi |
| 504 | |
| 505 | echo "Running Robot Framework tests..." |
| 506 | mkdir -p "$LOGS_DIR" |
| 507 | export ROBOT_MISC_ARGS="-d ${LOGS_DIR} ${EXTRA_ROBOT_ARGS}" |
| 508 | ROBOT_MISC_ARGS="${ROBOT_MISC_ARGS} -v ONOS_SSH_PORT:30115" |
| 509 | ROBOT_MISC_ARGS="${ROBOT_MISC_ARGS} -v ONOS_REST_PORT:30120" |
| 510 | ROBOT_MISC_ARGS="${ROBOT_MISC_ARGS} -v NAMESPACE:${VOLTHA_NAMESPACE}" |
| 511 | ROBOT_MISC_ARGS="${ROBOT_MISC_ARGS} -v INFRA_NAMESPACE:${INFRA_NAMESPACE}" |
| 512 | ROBOT_MISC_ARGS="${ROBOT_MISC_ARGS} -v container_log_dir:${LOGS_DIR}" |
| 513 | ROBOT_MISC_ARGS="${ROBOT_MISC_ARGS} -v logging:${TEST_LOGGING}" |
| 514 | export ROBOT_MISC_ARGS |
| 515 | export KVSTOREPREFIX="voltha/voltha_voltha" |
| 516 | cd "$GITHUB_WORKSPACE/voltha-system-tests" |
| 517 | make "${TEST_TARGET}" || TEST_RESULT=$? |
| 518 | |
| 519 | get_pods_info "$LOGS_DIR" |
| 520 | |
| 521 | if [ "$WITH_MONITORING" = "true" ]; then |
| 522 | echo "Collecting final memory consumption..." |
| 523 | cd "$GITHUB_WORKSPACE/voltha-system-tests" |
| 524 | source .venv/bin/activate || true |
| 525 | if [ -f "scripts/mem_consumption.py" ]; then |
| 526 | python scripts/mem_consumption.py \ |
| 527 | -o "$GITHUB_WORKSPACE/voltha-pods-mem-consumption-${WORKFLOW}" \ |
| 528 | -a 0.0.0.0:31301 -n "$VOLTHA_NAMESPACE" || true |
| 529 | fi |
| 530 | fi |
| 531 | |
| 532 | echo "Compressing logs..." |
| 533 | cd "$LOGS_DIR" |
| 534 | gzip *-combined.log 2>/dev/null || true |
| 535 | banner "Test execution completed" |
| 536 | exit ${TEST_RESULT:-0} |
| 537 | EXECUTE_TEST_SCRIPT |
| 538 | |
| 539 | chmod +x /tmp/execute_test.sh |
| 540 | |
| 541 | - name: Execute tests |
| 542 | id: test-execution |
| 543 | shell: bash |
| 544 | run: | |
| 545 | echo "Executing tests..." |
| 546 | |
| 547 | # Create logs directory |
| 548 | mkdir -p $GITHUB_WORKSPACE/logs |
| 549 | echo "results-path=$GITHUB_WORKSPACE/logs" >> $GITHUB_OUTPUT |
| 550 | |
| 551 | # Parse test targets from YAML |
| 552 | cat > /tmp/test-targets.yaml <<'EOF' |
| 553 | ${{ inputs.test-targets }} |
| 554 | EOF |
| 555 | |
| 556 | # Run each test target |
| 557 | python3 - <<'PYTHON_SCRIPT' |
| 558 | import yaml |
| 559 | import subprocess |
| 560 | import os |
| 561 | import sys |
| 562 | |
| 563 | with open('/tmp/test-targets.yaml', 'r') as f: |
| 564 | tests = yaml.safe_load(f) |
| 565 | |
| 566 | if not tests: |
| 567 | print("No tests defined") |
| 568 | sys.exit(0) |
| 569 | |
| 570 | workspace = os.environ['GITHUB_WORKSPACE'] |
| 571 | test_failures = [] |
| 572 | |
| 573 | for idx, test in enumerate(tests): |
| 574 | target = test.get('target', '') |
| 575 | workflow = test.get('workflow', '') |
| 576 | flags = test.get('flags', '') |
| 577 | teardown = test.get('teardown', True) |
| 578 | logging = test.get('logging', True) |
| 579 | vgc_enabled = test.get('vgcEnabled', False) |
| 580 | |
| 581 | print(f"\n** -----------------------------------------------------------------------") |
| 582 | print(f"** Executing test {target} on workflow {workflow}") |
| 583 | print(f"** -----------------------------------------------------------------------\n") |
| 584 | |
| 585 | # Set environment variables |
| 586 | env = os.environ.copy() |
| 587 | env['TEST_TARGET'] = target |
| 588 | env['WORKFLOW'] = workflow |
| 589 | env['TEST_FLAGS'] = flags |
| 590 | env['TEARDOWN'] = str(teardown).lower() |
| 591 | env['TEST_LOGGING'] = 'True' if logging else 'False' |
| 592 | env['VGC_ENABLED'] = 'true' if vgc_enabled else 'false' |
| 593 | env['INFRA_NAMESPACE'] = 'default' |
| 594 | env['VOLTHA_NAMESPACE'] = 'voltha' |
| 595 | env['LOGS_DIR'] = f"{workspace}/logs/{target}" |
| 596 | env['EXTRA_HELM_FLAGS'] = "${{ inputs.extra-helm-flags }}" |
| 597 | env['LOG_LEVEL'] = "${{ inputs.log-level }}" |
| 598 | env['DOCKER_REGISTRY'] = "${{ inputs.docker-registry }}" |
| 599 | env['OLTS'] = "${{ inputs.olts }}" |
| 600 | env['WITH_MONITORING'] = "${{ inputs.with-monitoring }}" |
| 601 | env['ENABLE_MAC_LEARNING'] = "${{ inputs.enable-mac-learning }}" |
| 602 | env['EXTRA_ROBOT_ARGS'] = "${{ inputs.extra-robot-args }}" |
| 603 | env['BRANCH'] = "${{ inputs.branch }}" |
| 604 | env['GERRIT_PROJECT'] = "${{ inputs.gerrit-project }}" |
| 605 | |
| 606 | # Create logs directory for this test |
| 607 | os.makedirs(env['LOGS_DIR'], exist_ok=True) |
| 608 | |
| 609 | # Execute the test using the inline script |
| 610 | script_path = "/tmp/execute_test.sh" |
| 611 | |
| 612 | print(f"Running test script: {script_path}") |
| 613 | |
| 614 | try: |
| 615 | result = subprocess.run( |
| 616 | ['/bin/bash', script_path], |
| 617 | env=env, |
| 618 | check=True |
| 619 | ) |
| 620 | print(f"\nTest {target} completed successfully\n") |
| 621 | except subprocess.CalledProcessError as e: |
| 622 | print(f"\nTest {target} failed with exit code {e.returncode}\n") |
| 623 | test_failures.append(target) |
| 624 | # Continue with other tests |
| 625 | continue |
| 626 | except Exception as e: |
| 627 | print(f"\nTest {target} failed with exception: {e}\n") |
| 628 | test_failures.append(target) |
| 629 | continue |
| 630 | |
| 631 | if test_failures: |
| 632 | print(f"\n** Failed tests: {', '.join(test_failures)}") |
| 633 | sys.exit(1) |
| 634 | else: |
| 635 | print("\n** All tests passed successfully") |
| 636 | |
| 637 | PYTHON_SCRIPT |
| 638 | |
| 639 | # ----------------------------------------------------------------------- |
| 640 | # Collect artifacts |
| 641 | # ----------------------------------------------------------------------- |
| 642 | - name: Collect pod information |
| 643 | if: always() |
| 644 | shell: bash |
| 645 | run: | |
| 646 | echo "Collecting pod information..." |
| 647 | mkdir -p $GITHUB_WORKSPACE/logs/artifacts |
| 648 | |
| 649 | kubectl get pods --all-namespaces -o wide > $GITHUB_WORKSPACE/logs/artifacts/pods.txt || true |
| 650 | kubectl get nodes -o wide > $GITHUB_WORKSPACE/logs/artifacts/nodes.txt || true |
| 651 | kubectl get events --all-namespaces --sort-by='.lastTimestamp' > $GITHUB_WORKSPACE/logs/artifacts/events.txt || true |
| 652 | |
| 653 | - name: Collect VOLTHA logs |
| 654 | if: always() |
| 655 | shell: bash |
| 656 | run: | |
| 657 | echo "Collecting VOLTHA logs..." |
| 658 | kubectl logs -n voltha -l app.kubernetes.io/part-of=voltha \ |
| 659 | > $GITHUB_WORKSPACE/logs/artifacts/voltha.log || true |
| 660 | |
| 661 | - name: Cleanup port-forward processes |
| 662 | if: always() |
| 663 | shell: bash |
| 664 | run: | |
| 665 | echo "Cleaning up port-forward processes..." |
| 666 | pkill -f "kubectl.*port-forward" || true |
| 667 | |
| 668 | - name: Upload test results |
| 669 | if: always() |
| 670 | uses: actions/upload-artifact@v4 |
| 671 | with: |
| 672 | name: bbsim-test-results-${{ github.run_id }} |
| 673 | path: | |
| 674 | ${{ github.workspace }}/logs/**/*.log |
| 675 | ${{ github.workspace }}/logs/**/*.gz |
| 676 | ${{ github.workspace }}/logs/**/*.txt |
| 677 | ${{ github.workspace }}/logs/**/*.html |
| 678 | ${{ github.workspace }}/logs/**/*.xml |
| 679 | ${{ github.workspace }}/logs/**/voltha-pods-mem-consumption-*/* |
| 680 | retention-days: 30 |
| 681 | if-no-files-found: warn |
| 682 | |
| 683 | # ----------------------------------------------------------------------- |
| 684 | # Cleanup |
| 685 | # ----------------------------------------------------------------------- |
| 686 | - name: Delete kind cluster |
| 687 | if: always() |
| 688 | shell: bash |
| 689 | run: | |
| 690 | # Note: Cluster deletion is optional and can be controlled by workflow |
| 691 | echo "To delete cluster manually, run: kind delete cluster --name ${{ inputs.cluster-name }}" |