Commit 80053007 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

QKD E2E Test:

- Conveniently renamed descriptor files
- Defined scripts and python test code
- Updated Dockerfile and requirements.in
- Added convenience microk8s status wait ready in redeploy-all script
- Added QKD App service in log dump script
- Updated QKD_E2E GitlabCI/CD pipeline descriptor
- Updated README.md and merged commands.txt on it
parent 281a132d
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+136 −42
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ build qkd_end2end:

# Deploy TeraFlowSDN and Execute end-2-end test
end2end_test qkd_end2end:
  timeout: 30m
  variables:
    TEST_NAME: 'qkd_end2end'
  stage: end2end_test
@@ -68,59 +69,156 @@ end2end_test qkd_end2end:
      --volume "$PWD/data/qkd-node-03.json:/var/mock_qkd_node/startup.json"
      mock-qkd-node:test

    # Dump configuration of the QKD Nodes (script, before any configuration)
    - echo "[QKD-NODE-01] Config initial:"
    - curl "http://172.254.250.101:8080/restconf/data/etsi-qkd-sdn-node:"
    - echo
    - echo "[QKD-NODE-02] Config initial:"
    - curl "http://172.254.250.102:8080/restconf/data/etsi-qkd-sdn-node:"
    - echo
    - echo "[QKD-NODE-03] Config initial:"
    - curl "http://172.254.250.103:8080/restconf/data/etsi-qkd-sdn-node:"
    - echo

    # Check MicroK8s is ready
    - microk8s status --wait-ready
    - kubectl get pods --all-namespaces

    # Configure TeraFlowSDN deployment
    # Uncomment if DEBUG log level is needed for the components
    #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/contextservice.yaml
    #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/deviceservice.yaml
    #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="frontend").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/pathcompservice.yaml
    #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/serviceservice.yaml
    #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/nbiservice.yaml
    #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/qkd_appservice.yaml

    - source src/tests/${TEST_NAME}/deploy_specs.sh
    #- export TFS_REGISTRY_IMAGES="${CI_REGISTRY_IMAGE}"
    #- export TFS_SKIP_BUILD="YES"
    #- export TFS_IMAGE_TAG="latest"
    #- echo "TFS_REGISTRY_IMAGES=${CI_REGISTRY_IMAGE}"

    # Deploy TeraFlowSDN
    - ./deploy/crdb.sh
    - ./deploy/nats.sh
    - ./deploy/kafka.sh
    #- ./deploy/qdb.sh
    - ./deploy/tfs.sh
    - ./deploy/show.sh

    ## Wait for Context to be subscribed to NATS
    ## WARNING: this loop is infinite if there is no subscriber (such as monitoring).
    ##          Investigate if we can use a counter to limit the number of iterations.
    ##          For now, keep it commented out.
    #- LOOP_MAX_ATTEMPTS=180
    #- LOOP_COUNTER=0
    #- >
    #  while ! kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server 2>&1 | grep -q 'Subscriber is Ready? True'; do
    #    echo "Attempt: $LOOP_COUNTER"
    #    kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server 2>&1;
    #    sleep 1;
    #    LOOP_COUNTER=$((LOOP_COUNTER + 1))
    #    if [ "$LOOP_COUNTER" -ge "$LOOP_MAX_ATTEMPTS" ]; then
    #      echo "Max attempts reached, exiting the loop."
    #      break
    #    fi
    #  done
    - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server

    # Run end-to-end test: onboard scenario
    - >
      docker run -t --rm --name ${TEST_NAME} --network=host 
      --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh"
      --volume "$PWD/src/tests/${TEST_NAME}:/opt/results"
      $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-01-onboarding.sh

    # Wait for CockroachDB and NATS to initialize
    - echo "Waiting for CockroachDB to be ready..."
    - while ! docker logs crdb 2>&1 | grep -q 'CockroachDB node starting'; do sleep 1; done
    - docker logs crdb
    - echo "Waiting for NATS to be ready..."
    - while ! docker logs nats 2>&1 | grep -q 'Server is ready'; do sleep 1; done
    - docker logs nats
    # Run end-to-end test: create QKD links
    - >
      docker run -t --rm --name ${TEST_NAME} --network=host 
      --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh"
      --volume "$PWD/src/tests/${TEST_NAME}:/opt/results"
      $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-02-create-links.sh

    # Dump configuration of the QKD Nodes (script, after create QKD links)
    - echo "[QKD-NODE-01] Config with links:"
    - curl "http://172.254.250.101:8080/restconf/data/etsi-qkd-sdn-node:"
    - echo
    - echo "[QKD-NODE-02] Config with links:"
    - curl "http://172.254.250.102:8080/restconf/data/etsi-qkd-sdn-node:"
    - echo
    - echo "[QKD-NODE-03] Config with links:"
    - curl "http://172.254.250.103:8080/restconf/data/etsi-qkd-sdn-node:"
    - echo

    # TODO: check config of QKD Nodes with created links is correct

    # Run end-to-end test: create external app
    - >
      docker run -t --rm --name ${TEST_NAME} --network=host 
      --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh"
      --volume "$PWD/src/tests/${TEST_NAME}:/opt/results"
      $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-03-create-external-app.sh

    # Start mock QKD nodes
    - docker run --name mock_qkd -d --network=teraflowbridge -v "$PWD/src/tests/tools/mock_qkd_nodes:/app" python:3.9-slim bash -c "cd /app && ./start.sh"
    # Dump configuration of the QKD Nodes (script, after create external app)
    - echo "[QKD-NODE-01] Config with links and external app:"
    - curl "http://172.254.250.101:8080/restconf/data/etsi-qkd-sdn-node:"
    - echo
    - echo "[QKD-NODE-02] Config with links and external app:"
    - curl "http://172.254.250.102:8080/restconf/data/etsi-qkd-sdn-node:"
    - echo
    - echo "[QKD-NODE-03] Config with links and external app:"
    - curl "http://172.254.250.103:8080/restconf/data/etsi-qkd-sdn-node:"
    - echo

    # Wait for mock QKD nodes to initialize
    - echo "Waiting for mock QKD nodes to be ready..."
    - sleep 10
    # TODO: check config of QKD Nodes with created links and external app is correct

    # Deploy TeraFlowSDN services
    - CRDB_ADDRESS=$(docker inspect crdb --format "{{.NetworkSettings.Networks.teraflowbridge.IPAddress}}")
    - NATS_ADDRESS=$(docker inspect nats --format "{{.NetworkSettings.Networks.teraflowbridge.IPAddress}}")
    # Run end-to-end test: delete external app
    - >
      docker run -t --rm --name ${TEST_NAME} --network=host
      --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh"
      --volume "$PWD/src/tests/${TEST_NAME}:/opt/results"
      $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-04-delete-external-app.sh

    # Deploy Context Service
    - docker run --name context -d -p 1010:1010 --env "CRDB_URI=cockroachdb://tfs:tfs123@${CRDB_ADDRESS}:26257/tfs_test?sslmode=require" --env "MB_BACKEND=nats" --env "NATS_URI=nats://tfs:tfs123@${NATS_ADDRESS}:4222" --network=teraflowbridge $CI_REGISTRY_IMAGE/context:latest
    - CONTEXTSERVICE_SERVICE_HOST=$(docker inspect context --format "{{.NetworkSettings.Networks.teraflowbridge.IPAddress}}")
    # Dump configuration of the QKD Nodes (script, after delete external app)
    - echo "[QKD-NODE-01] Config with links and deleted external app:"
    - curl "http://172.254.250.101:8080/restconf/data/etsi-qkd-sdn-node:"
    - echo
    - echo "[QKD-NODE-02] Config with links and deleted external app:"
    - curl "http://172.254.250.102:8080/restconf/data/etsi-qkd-sdn-node:"
    - echo
    - echo "[QKD-NODE-03] Config with links and deleted external app:"
    - curl "http://172.254.250.103:8080/restconf/data/etsi-qkd-sdn-node:"
    - echo

    # Deploy Device Service
    - docker run --name device -d -p 2020:2020 --env "CONTEXTSERVICE_SERVICE_HOST=${CONTEXTSERVICE_SERVICE_HOST}" --network=teraflowbridge $CI_REGISTRY_IMAGE/device:latest
    - DEVICESERVICE_SERVICE_HOST=$(docker inspect device --format "{{.NetworkSettings.Networks.teraflowbridge.IPAddress}}")
    # TODO: check config of QKD Nodes with created links and deleted external app is correct

    # Deploy PathComp Services (frontend and backend)
    - docker run --name pathcomp-backend -d -p 8081:8081 --network=teraflowbridge $CI_REGISTRY_IMAGE/pathcomp-backend:latest
    - PATHCOMP_BACKEND_HOST=$(docker inspect pathcomp-backend --format "{{.NetworkSettings.Networks.teraflowbridge.IPAddress}}")
    - docker run --name pathcomp-frontend -d -p 10020:10020 --env "CONTEXTSERVICE_SERVICE_HOST=${CONTEXTSERVICE_SERVICE_HOST}" --env "PATHCOMP_BACKEND_HOST=${PATHCOMP_BACKEND_HOST}" --env "PATHCOMP_BACKEND_PORT=8081" --network=teraflowbridge $CI_REGISTRY_IMAGE/pathcomp-frontend:latest
    - PATHCOMPSERVICE_SERVICE_HOST=$(docker inspect pathcomp-frontend --format "{{.NetworkSettings.Networks.teraflowbridge.IPAddress}}")
    # Run end-to-end test: delete QKD links
    - >
      docker run -t --rm --name ${TEST_NAME} --network=host 
      --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh"
      --volume "$PWD/src/tests/${TEST_NAME}:/opt/results"
      $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-05-delete-links.sh

    # Deploy Service Component
    - docker run --name service -d -p 3030:3030 --env "CONTEXTSERVICE_SERVICE_HOST=${CONTEXTSERVICE_SERVICE_HOST}" --env "DEVICESERVICE_SERVICE_HOST=${DEVICESERVICE_SERVICE_HOST}" --env "PATHCOMPSERVICE_SERVICE_HOST=${PATHCOMPSERVICE_SERVICE_HOST}" --volume "$PWD/src/service/tests:/opt/results" --network=teraflowbridge $CI_REGISTRY_IMAGE/service:latest
    # Dump configuration of the QKD Nodes (script, after delete QKD links)
    - echo "[QKD-NODE-01] Config with deleted links and deleted external app:"
    - curl "http://172.254.250.101:8080/restconf/data/etsi-qkd-sdn-node:"
    - echo
    - echo "[QKD-NODE-02] Config with deleted links and deleted external app:"
    - curl "http://172.254.250.102:8080/restconf/data/etsi-qkd-sdn-node:"
    - echo
    - echo "[QKD-NODE-03] Config with deleted links and deleted external app:"
    - curl "http://172.254.250.103:8080/restconf/data/etsi-qkd-sdn-node:"
    - echo

    # Wait for services to initialize
    - sleep 10
    # TODO: check config of QKD Nodes with deleted links and deleted external app is correct

    # Run end-to-end tests for QKD application
    # Run end-to-end test: cleanup scenario
    - >
      docker run -t --rm --name ${TEST_NAME} --network=host 
      --volume "$PWD/tfs_runtime_env_vars.sh:/var/teraflow/tfs_runtime_env_vars.sh"
      --volume "$PWD/src/tests/${TEST_NAME}:/opt/results"
      $CI_REGISTRY_IMAGE/${TEST_NAME}:latest
      $CI_REGISTRY_IMAGE/${TEST_NAME}:latest /var/teraflow/run-06-cleanup.sh

  after_script:
    # Dump configuration of the QKD Nodes (after_script)
@@ -139,13 +237,6 @@ end2end_test qkd_end2end:
    - docker logs qkd-node-02
    - docker logs qkd-node-03

    # Dump logs for TeraFlowSDN components
    - docker logs context
    - docker logs device
    - docker logs pathcomp-frontend
    - docker logs pathcomp-backend
    - docker logs service

    # Dump TeraFlowSDN component logs
    - source src/tests/${TEST_NAME}/deploy_specs.sh
    - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server
@@ -156,10 +247,13 @@ end2end_test qkd_end2end:
    - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/qkd-appservice -c server

    # Clean up
    - docker rm -f context device pathcomp-frontend pathcomp-backend service mock_qkd crdb nats
    - docker network rm teraflowbridge
    - docker rm -f ${TEST_NAME} || true
    - kubectl delete namespaces tfs || true
    - docker rm --force qkd-node-01 qkd-node-02 qkd-node-03
    - docker network rm --force qkd-node-br
    - docker volume prune --force
    - docker image prune --force

    # Clean old docker images
    - docker images --filter="dangling=true" --quiet | xargs -r docker rmi

+86 −0
Original line number Diff line number Diff line
# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

FROM python:3.9-slim

# Install dependencies
RUN apt-get --yes --quiet --quiet update && \
    apt-get --yes --quiet --quiet install wget g++ git && \
    rm -rf /var/lib/apt/lists/*

# Set Python to show logs as they occur
ENV PYTHONUNBUFFERED=0

# Get generic Python packages
RUN python3 -m pip install --upgrade pip
RUN python3 -m pip install --upgrade setuptools wheel
RUN python3 -m pip install --upgrade pip-tools

# Get common Python packages
# Note: this step enables sharing the previous Docker build steps among all the Python components
WORKDIR /var/teraflow
COPY common_requirements.in common_requirements.in
RUN pip-compile --quiet --output-file=common_requirements.txt common_requirements.in
RUN python3 -m pip install -r common_requirements.txt

# Add common files into working directory
WORKDIR /var/teraflow/common
COPY src/common/. ./
RUN rm -rf proto

# Create proto sub-folder, copy .proto files, and generate Python code
RUN mkdir -p /var/teraflow/common/proto
WORKDIR /var/teraflow/common/proto
RUN touch __init__.py
COPY proto/*.proto ./
RUN python3 -m grpc_tools.protoc -I=. --python_out=. --grpc_python_out=. *.proto
RUN rm *.proto
RUN find . -type f -exec sed -i -E 's/^(import\ .*)_pb2/from . \1_pb2/g' {} \;

# Create component sub-folders, get specific Python packages
RUN mkdir -p /var/teraflow/tests/qkd_end2end
WORKDIR /var/teraflow/tests/qkd_end2end
COPY src/tests/qkd_end2end/requirements.in requirements.in
RUN pip-compile --quiet --output-file=requirements.txt requirements.in
RUN python3 -m pip install -r requirements.txt

# Add component files into working directory
WORKDIR /var/teraflow
COPY src/__init__.py ./__init__.py
COPY src/common/*.py ./common/
COPY src/common/tests/. ./common/tests/
COPY src/common/tools/. ./common/tools/
COPY src/context/__init__.py context/__init__.py
COPY src/context/client/. context/client/
COPY src/device/__init__.py device/__init__.py
COPY src/device/client/. device/client/
COPY src/monitoring/__init__.py monitoring/__init__.py
COPY src/monitoring/client/. monitoring/client/
COPY src/service/__init__.py service/__init__.py
COPY src/service/client/. service/client/
COPY src/slice/__init__.py slice/__init__.py
COPY src/slice/client/. slice/client/
COPY src/vnt_manager/__init__.py vnt_manager/__init__.py
COPY src/vnt_manager/client/. vnt_manager/client/
COPY src/tests/*.py ./tests/
COPY src/tests/qkd_end2end/__init__.py ./tests/qkd_end2end/__init__.py
COPY src/tests/qkd_end2end/data/. ./tests/qkd_end2end/data/
COPY src/tests/qkd_end2end/tests/. ./tests/qkd_end2end/tests/
COPY src/tests/qkd_end2end/scripts/. ./

RUN apt-get --yes --quiet --quiet update && \
    apt-get --yes --quiet --quiet install tree && \
    rm -rf /var/lib/apt/lists/*

RUN tree -la /var/teraflow
+48 −0
Original line number Diff line number Diff line
# QKD End-to-End Test

## Emulated QKD Nodes
See `src/tests/tools/mock_qkd_node`.
Here we deploy 3 emulated QKD Nodes initialized with configurations `data/qkd-node-XX.json`.

### (Re-)Deploy the 3 QKD Nodes
```bash
cd ~/tfs-ctrl
./src/tests/qkd_end2end/redeploy-qkd-nodes.sh
```

### Check their configuration
```bash
curl http://<mgmt-ip-addr>:<mgmt-port>/restconf/data/etsi-qkd-sdn-node:
```

### Update their configuration using root path
```bash
curl -X PATCH -d '{"qkd_node":{"qkdn_location_id":"new-loc"}}' http://<mgmt-ip-addr>:<mgmt-port>/restconf/data/etsi-qkd-sdn-node:
```

### Update their configuration using sub-entity path
```bash
curl -X PATCH -d '{"qkdn_location_id":"new-loc-2"}' http://<mgmt-ip-addr>:<mgmt-port>/restconf/data/etsi-qkd-sdn-node:qkd_node
```

### Destroy scenario
```bash
docker rm --force qkd-node-01 qkd-node-02 qkd-node-03
docker network rm --force qkd-node-br
```

## TeraFlowSDN Deployment
```bash
cd ~/tfs-ctrl
./src/tests/qkd_end2end/redeploy-tfs.sh
```

### QKD Node Topology
The topology descriptor for the QKD nodes is: `data/tfs-01-topology.json`

### Dump TFS component logs to files
```bash
cd ~/tfs-ctrl
./src/tests/qkd_end2end/dump_logs.sh
```
Will create files `<comp-name>.log`
+14 −0
Original line number Diff line number Diff line
# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
Loading