From cb62ef5b4269e4c76bd3093171ea7d1a065892f9 Mon Sep 17 00:00:00 2001 From: phine-richiB Date: Wed, 1 Apr 2026 16:09:27 +0200 Subject: [PATCH 1/4] fet/added ci for 5g connectivity --- .github/workflows/ci.yml | 2 +- .github/workflows/integration-test.yml | 120 ++++++++++++++++ tests/integration/check_registration.sh | 135 ++++++++++++++++++ .../docker-compose-test-simulation.yml | 44 ++++++ 4 files changed, 300 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/integration-test.yml create mode 100755 tests/integration/check_registration.sh create mode 100644 tests/integration/docker-compose-test-simulation.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 11eeda1..c66da00 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: CI on: push: - branches: [ main] + branches: [ feat/ci_test_plugins_amf, main ] pull_request: branches: [ main ] diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml new file mode 100644 index 0000000..fd0217b --- /dev/null +++ b/.github/workflows/integration-test.yml @@ -0,0 +1,120 @@ +name: Integration Test + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + integration-test: + runs-on: ubuntu-latest + timeout-minutes: 60 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Free up disk space + run: | + sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc + sudo apt-get clean + df -h + + - name: Build UE and gNB plugins + run: | + docker run --rm \ + -v "${{ github.workspace }}:/workspace" \ + osrf/ros:humble-desktop \ + /bin/bash -c " + set -e + apt-get update && apt-get install -y \ + python3-colcon-common-extensions \ + wget lsb-release gnupg2 + + # Add Gazebo Ignition key and repo (Fortress) + echo 'deb http://packages.osrfoundation.org/gazebo/ubuntu-stable \$(lsb_release -cs) main' \ + > /etc/apt/sources.list.d/gazebo-stable.list + wget https://packages.osrfoundation.org/gazebo.key -O - | apt-key add - + apt-get update && apt-get install -y ignition-fortress + + cd /workspace/phine-plugins + source /opt/ros/humble/setup.bash + colcon build --event-handlers console_direct+ + + # Verify plugins were built + ls -la /workspace/phine-plugins/install/phine_plugins/lib/phine_plugins/ + " + + - name: Copy built plugins to simulation image + run: | + PLUGIN_SRC=phine-plugins/install/phine_plugins/lib/phine_plugins + PLUGIN_DST=demo_containerized/images/simulation/gazebo_launch/src/ign_turtlebot/phine_plugins + + cp "${PLUGIN_SRC}/libgNB_plugin.so" "${PLUGIN_DST}/libgNB_plugin.so" + cp "${PLUGIN_SRC}/libUE_plugin.so" "${PLUGIN_DST}/libUE_plugin.so" + + echo "Plugins copied:" + ls -la "${PLUGIN_DST}/" + + - name: Build simulation Docker image + run: | + cd demo_containerized/images/simulation + docker build -t simulation:test . + + - name: Start OAI Core Network + run: | + cd demo_containerized/oai_setup + docker compose up -d + ./wait_for_core_network.sh + + - name: Create ros_gz_net network + run: | + docker network create \ + --driver bridge \ + --subnet=192.168.73.128/26 \ + --opt com.docker.network.bridge.name="ros_gz_net" \ + ros_gz_net + + - name: Start simulation container (headless) + run: | + cd tests/integration + DEMO_PROJECT_PATH="${{ github.workspace }}/demo_containerized" \ + docker compose -f docker-compose-test-simulation.yml up -d + + - name: Check gNB and UE registration + run: | + chmod +x tests/integration/check_registration.sh + tests/integration/check_registration.sh 900 + + - name: Collect logs on failure + if: failure() + run: | + echo "=== AMF logs ===" + docker logs oai-amf 2>&1 | tail -100 || true + echo "" + echo "=== Simulation container logs ===" + docker logs simulation 2>&1 | tail -100 || true + echo "" + echo "=== gNB container logs ===" + docker logs oai-gNB1 2>&1 | tail -50 || true + echo "" + echo "=== UE container logs ===" + docker logs ue_turtlebot 2>&1 | tail -50 || true + echo "" + echo "=== All running containers ===" + docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" || true + echo "" + echo "=== Docker networks ===" + docker network ls || true + + - name: Cleanup + if: always() + run: | + cd tests/integration + docker compose -f docker-compose-test-simulation.yml down || true + docker stop ue_turtlebot oai-gNB1 2>/dev/null || true + docker rm ue_turtlebot oai-gNB1 2>/dev/null || true + cd "${{ github.workspace }}/demo_containerized/oai_setup" + docker compose down || true + docker network rm ros_gz_net 2>/dev/null || true diff --git a/tests/integration/check_registration.sh b/tests/integration/check_registration.sh new file mode 100755 index 0000000..46079bc --- /dev/null +++ b/tests/integration/check_registration.sh @@ -0,0 +1,135 @@ +#!/bin/bash +# Check OAI AMF logs for gNB and UE registration +# Usage: ./check_registration.sh [timeout_seconds] + +set -e + +TIMEOUT=${1:-600} +INTERVAL=15 +ELAPSED=0 + +GNB_CONTAINER_UP=false +UE_CONTAINER_UP=false +GNB_REGISTERED=false +UE_REGISTERED=false + +echo "============================================" +echo "Integration Test: gNB and UE Registration" +echo "Timeout: ${TIMEOUT}s" +echo "============================================" + +# Phase 1: Wait for gNB and UE containers to be started by the plugins +echo "" +echo "Phase 1: Waiting for gNB and UE containers to appear..." +echo "(The UE plugin builds a Docker image first, this can take several minutes)" +echo "" + +while [ $ELAPSED -lt $TIMEOUT ]; do + # Check if gNB container exists + if [ "$GNB_CONTAINER_UP" = false ]; then + if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "oai-gNB"; then + echo "[OK] gNB container is running (elapsed: ${ELAPSED}s)" + GNB_CONTAINER_UP=true + fi + fi + + # Check if UE container exists (ue_turtlebot from the SDF config) + if [ "$UE_CONTAINER_UP" = false ]; then + if docker ps --format '{{.Names}}' 2>/dev/null | grep -qE "(ue_turtlebot|robot_1)"; then + echo "[OK] UE container is running (elapsed: ${ELAPSED}s)" + UE_CONTAINER_UP=true + fi + fi + + # Both containers running, move to phase 2 + if [ "$GNB_CONTAINER_UP" = true ] && [ "$UE_CONTAINER_UP" = true ]; then + echo "" + echo "Phase 2: Checking AMF logs for registration..." + echo "" + break + fi + + # Show what's happening + if [ $((ELAPSED % 60)) -eq 0 ] && [ $ELAPSED -gt 0 ]; then + echo " Still waiting... (elapsed: ${ELAPSED}s)" + echo " Running containers:" + docker ps --format " {{.Names}} ({{.Status}})" 2>/dev/null || true + else + echo " Waiting... gNB_container=${GNB_CONTAINER_UP} UE_container=${UE_CONTAINER_UP} (elapsed: ${ELAPSED}s)" + fi + + sleep $INTERVAL + ELAPSED=$((ELAPSED + INTERVAL)) +done + +if [ "$GNB_CONTAINER_UP" = false ] || [ "$UE_CONTAINER_UP" = false ]; then + echo "============================================" + echo "[FAILURE] Timeout waiting for containers to start" + echo " gNB container running: ${GNB_CONTAINER_UP}" + echo " UE container running: ${UE_CONTAINER_UP}" + echo "============================================" + echo "" + echo "--- Running containers ---" + docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" 2>/dev/null || true + echo "" + echo "--- Simulation container logs (last 50 lines) ---" + docker logs simulation 2>&1 | tail -50 || true + exit 1 +fi + +# Phase 2: Check AMF logs for registration +while [ $ELAPSED -lt $TIMEOUT ]; do + AMF_LOGS=$(docker logs oai-amf 2>&1 || echo "") + + # Check for gNB registration + if echo "$AMF_LOGS" | grep -qiE "(gNB.*associated|NG_SETUP.*SUCCESS|Connected.*gNB|gNodeB.*context)"; then + if [ "$GNB_REGISTERED" = false ]; then + echo "[PASS] gNB registered with AMF (elapsed: ${ELAPSED}s)" + GNB_REGISTERED=true + fi + fi + + # Check for UE registration + if echo "$AMF_LOGS" | grep -qiE "(registration.*accept|5GMM-REGISTERED|UE.*registered|InitialUEMessage|REGISTRATION_COMPLETE)"; then + if [ "$UE_REGISTERED" = false ]; then + echo "[PASS] UE registered with AMF (elapsed: ${ELAPSED}s)" + UE_REGISTERED=true + fi + fi + + # Both registered - success + if [ "$GNB_REGISTERED" = true ] && [ "$UE_REGISTERED" = true ]; then + echo "" + echo "============================================" + echo "[SUCCESS] Both gNB and UE are registered with the AMF" + echo "============================================" + echo "" + echo "--- Relevant AMF log lines ---" + docker logs oai-amf 2>&1 | grep -iE "(gNB|UE|registration|associated|connected|NGAP)" | tail -20 || true + exit 0 + fi + + echo " Checking AMF... gNB=${GNB_REGISTERED} UE=${UE_REGISTERED} (elapsed: ${ELAPSED}s)" + sleep $INTERVAL + ELAPSED=$((ELAPSED + INTERVAL)) +done + +echo "" +echo "============================================" +echo "[FAILURE] Timeout after ${TIMEOUT}s" +echo " gNB registered: ${GNB_REGISTERED}" +echo " UE registered: ${UE_REGISTERED}" +echo "============================================" +echo "" +echo "--- AMF logs (last 80 lines) ---" +docker logs oai-amf 2>&1 | tail -80 || true +echo "" +echo "--- gNB container logs ---" +docker logs oai-gNB1 2>&1 | tail -30 || true +echo "" +echo "--- UE container logs ---" +docker logs ue_turtlebot 2>&1 | tail -30 || true +echo "" +echo "--- Running containers ---" +docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" 2>/dev/null || true +exit 1 diff --git a/tests/integration/docker-compose-test-simulation.yml b/tests/integration/docker-compose-test-simulation.yml new file mode 100644 index 0000000..3dcee73 --- /dev/null +++ b/tests/integration/docker-compose-test-simulation.yml @@ -0,0 +1,44 @@ +version: '3.8' +services: + simulation: + image: simulation:test + privileged: true + container_name: simulation + environment: + - PROJECT_PATH=/app + - DEMO_PROJECT_PATH=${DEMO_PROJECT_PATH} + - ROS_DISCOVERY_SERVER=192.168.70.159:11811 + - IGN_IP=192.168.73.151 + - ROS_DOMAIN_ID=10 + - IGN_PARTITION=domain1 + volumes: + - /var/run/docker.sock:/var/run/docker.sock + stdin_open: true + tty: true + networks: + public_net: + ipv4_address: 192.168.70.152 + ros_gz_net: + ipv4_address: 192.168.73.151 + entrypoint: + - /bin/bash + - -c + - | + source /opt/ros/humble/setup.bash + source /app/gazebo_launch/install/setup.bash + export FASTRTPS_DEFAULT_PROFILES_FILE=/app/dds.xml + PACKAGE_PATH=$$(ros2 pkg prefix ign_turtlebot --share) + export IGN_GAZEBO_RESOURCE_PATH=$${PACKAGE_PATH}/models:/opt/ros/humble/share + export IGN_GAZEBO_SYSTEM_PLUGIN_PATH=$${PACKAGE_PATH}/phine_plugins:/usr/lib/x86_64-linux-gnu/ign-gazebo-6/plugins:/opt/ros/humble/lib + export IGN_GUI_PLUGIN_PATH=$${PACKAGE_PATH}/gui_plugins + ip route add 10.0.0.0/16 via 192.168.70.134 dev eth0 || true + echo "Starting Gazebo in headless (server-only) mode..." + ign gazebo -s -r -v 3 $${PACKAGE_PATH}/worlds/world_only.sdf & + tail -f /dev/null +networks: + public_net: + external: + name: phine-net + ros_gz_net: + external: + name: ros_gz_net From ae38f8d8d9b6025dcc719e100b06f13c76a3d967 Mon Sep 17 00:00:00 2001 From: phine-richiB Date: Wed, 1 Apr 2026 16:15:30 +0200 Subject: [PATCH 2/4] fix/adjust CI --- .github/workflows/integration-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index fd0217b..758b2b8 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -2,7 +2,7 @@ name: Integration Test on: push: - branches: [ main ] + branches: [ feat/ci_test_plugins_amf, main ] pull_request: branches: [ main ] From 5356fabdd701b5e13f32a77f9c21b12e349759f7 Mon Sep 17 00:00:00 2001 From: phine-richiB Date: Wed, 1 Apr 2026 16:19:58 +0200 Subject: [PATCH 3/4] fix/ci --- .github/workflows/integration-test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 758b2b8..24ef25f 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -26,14 +26,14 @@ jobs: docker run --rm \ -v "${{ github.workspace }}:/workspace" \ osrf/ros:humble-desktop \ - /bin/bash -c " + /bin/bash -c ' set -e apt-get update && apt-get install -y \ python3-colcon-common-extensions \ wget lsb-release gnupg2 # Add Gazebo Ignition key and repo (Fortress) - echo 'deb http://packages.osrfoundation.org/gazebo/ubuntu-stable \$(lsb_release -cs) main' \ + echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" \ > /etc/apt/sources.list.d/gazebo-stable.list wget https://packages.osrfoundation.org/gazebo.key -O - | apt-key add - apt-get update && apt-get install -y ignition-fortress @@ -44,7 +44,7 @@ jobs: # Verify plugins were built ls -la /workspace/phine-plugins/install/phine_plugins/lib/phine_plugins/ - " + ' - name: Copy built plugins to simulation image run: | From a618e49464b89da72c8abf01b7dcc0eb196924a4 Mon Sep 17 00:00:00 2001 From: phine-richiB Date: Wed, 1 Apr 2026 16:41:51 +0200 Subject: [PATCH 4/4] fix/remove ci from branch --- .github/workflows/ci.yml | 2 +- .github/workflows/integration-test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c66da00..672b592 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: CI on: push: - branches: [ feat/ci_test_plugins_amf, main ] + branches: [ main ] pull_request: branches: [ main ] diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 24ef25f..ffb8f0a 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -2,7 +2,7 @@ name: Integration Test on: push: - branches: [ feat/ci_test_plugins_amf, main ] + branches: [ main ] pull_request: branches: [ main ]