diff --git a/src/tests/ofc24/.gitlab-ci.yml b/src/tests/ofc24/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0b5593b160ee14941546242dd3a4c3571407dedf
--- /dev/null
+++ b/src/tests/ofc24/.gitlab-ci.yml
@@ -0,0 +1,106 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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.
+
+# Build, tag, and push the Docker image to the GitLab Docker registry
+build ofc22:
+  variables:
+    TEST_NAME: 'ofc22'
+  stage: build
+  before_script:
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+  script:
+    - docker buildx build -t "${TEST_NAME}:latest" -f ./src/tests/${TEST_NAME}/Dockerfile .
+    - docker tag "${TEST_NAME}:latest" "$CI_REGISTRY_IMAGE/${TEST_NAME}:latest"
+    - docker push "$CI_REGISTRY_IMAGE/${TEST_NAME}:latest"
+  after_script:
+    - docker images --filter="dangling=true" --quiet | xargs -r docker rmi
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
+    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"'
+    - changes:
+      - src/common/**/*.py
+      - proto/*.proto
+      - src/tests/${TEST_NAME}/**/*.{py,in,sh,yml}
+      - src/tests/${TEST_NAME}/Dockerfile
+      - .gitlab-ci.yml
+
+# Deploy TeraFlowSDN and Execute end-2-end test
+end2end_test ofc22:
+  variables:
+    TEST_NAME: 'ofc22'
+  stage: end2end_test
+  # Disable to force running it after all other tasks
+  #needs:
+  #  - build ofc22
+  before_script:
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+  script:
+    # Download Docker image to run the test
+    - docker pull "${CI_REGISTRY_IMAGE}/${TEST_NAME}:latest"
+
+    # 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/sliceservice.yaml
+    #- yq -i '((select(.kind=="Deployment").spec.template.spec.containers.[] | select(.name=="server").env.[]) | select(.name=="LOG_LEVEL").value) |= "DEBUG"' manifests/nbiservice.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/qdb.sh
+    - ./deploy/expose_dashboard.sh
+    - ./deploy/tfs.sh
+    - ./deploy/show.sh
+    
+    # Wait for Context to be subscribed to NATS
+    #- while ! kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server 2>&1 | grep -q 'Subscriber is Ready? True'; do sleep 1; done
+    #- kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server
+
+    # Run end-to-end tests
+    - if docker ps -a | grep ${TEST_NAME}; then docker rm -f ${TEST_NAME}; fi
+    - >
+      docker run -t --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
+  after_script:
+    - source src/tests/${TEST_NAME}/deploy_specs.sh
+    - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/contextservice -c server
+    - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/deviceservice -c server
+    - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/pathcompservice -c frontend
+    - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/serviceservice -c server
+    - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/sliceservice -c server
+    - kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/nbiservice -c server
+    - if docker ps -a | grep ${TEST_NAME}; then docker rm -f ${TEST_NAME}; fi
+    - docker images --filter="dangling=true" --quiet | xargs -r docker rmi
+  #coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
+    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"'
+  artifacts:
+      when: always
+      reports:
+        junit: ./src/tests/${TEST_NAME}/report_*.xml
diff --git a/src/tests/ofc24/Dockerfile b/src/tests/ofc24/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..8efa0c72c3bdc72bd336d10a4ffdbc0af025fc25
--- /dev/null
+++ b/src/tests/ofc24/Dockerfile
@@ -0,0 +1,101 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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
+
+# Download the gRPC health probe
+RUN GRPC_HEALTH_PROBE_VERSION=v0.2.0 && \
+    wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \
+    chmod +x /bin/grpc_health_probe
+
+# 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/ofc24
+WORKDIR /var/teraflow/tests/ofc24
+COPY src/tests/ofc24/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/monitoring/__init__.py monitoring/__init__.py
+#COPY src/monitoring/client/. monitoring/client/
+COPY src/e2e_orchestrator/__init__.py e2e_orchestrator/__init__.py
+COPY src/e2e_orchestrator/client/. e2e_orchestrator/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/tests/*.py ./tests/
+COPY src/tests/ofc24/__init__.py ./tests/ofc24/__init__.py
+COPY src/tests/ofc24/descriptors_topology.json ./tests/ofc24/descriptors_topology.json
+COPY src/tests/ofc24/tests/. ./tests/ofc24/tests/
+COPY src/tests/tools/. ./tests/tools/
+
+RUN tee ./run_tests.sh <<EOF
+#!/bin/bash
+source /var/teraflow/tfs_runtime_env_vars.sh
+export PYTHONPATH=/var/teraflow
+pytest --verbose --log-level=INFO /var/teraflow/tests/ofc24/tests/test_functional_bootstrap.py      --junitxml=/opt/results/report_bootstrap.xml
+pytest --verbose --log-level=INFO /var/teraflow/tests/ofc24/tests/test_functional_create_service.py --junitxml=/opt/results/report_create_service.xml
+pytest --verbose --log-level=INFO /var/teraflow/tests/ofc24/tests/test_functional_delete_service.py --junitxml=/opt/results/report_delete_service.xml
+pytest --verbose --log-level=INFO /var/teraflow/tests/ofc24/tests/test_functional_cleanup.py        --junitxml=/opt/results/report_cleanup.xml
+EOF
+RUN chmod ug+x ./run_tests.sh
+
+# Run the tests
+ENTRYPOINT ["./run_tests.sh"]
diff --git a/src/tests/ofc24/deploy-node-agents.sh b/src/tests/ofc24/deploy-node-agents.sh
new file mode 100755
index 0000000000000000000000000000000000000000..5c3c8d0d2a5c4e15f4d3dda6a00d90ff00b77539
--- /dev/null
+++ b/src/tests/ofc24/deploy-node-agents.sh
@@ -0,0 +1,84 @@
+#!/bin/bash
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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.
+
+TEST_NAME="ofc24"
+
+
+echo
+echo "Pre-deploy clean-up:"
+echo "--------------------"
+docker rm -f na-t1 na-t2 na-r1 na-r2
+docker network rm na-br
+
+
+echo
+echo "Pull Docker images:"
+echo "-------------------"
+docker pull asgamb1/flexscale-hhi.img:latest
+docker pull asgamb1/flexscale-node.img:latest
+
+echo
+echo "Create Management Network and Node Agents:"
+echo "------------------------------------------"
+docker network create -d bridge --subnet=172.254.253.0/24 --gateway=172.254.253.254 --ip-range=172.254.253.0/24 na-br
+docker run -d --name na-t1 --network=na-br --ip 172.254.253.1 \
+    --volume "$PWD/src/tests/${TEST_NAME}/startNetconfAgent.sh:/confd/examples.confd/OC23/startNetconfAgent.sh" \
+    --volume "$PWD/src/tests/${TEST_NAME}/platform_t1.xml:/confd/examples.confd/OC23/init_openconfig-platform.xml" \
+    asgamb1/flexscale-hhi.img:latest /confd/examples.confd/OC23/startNetconfAgent.sh
+docker run -d --name na-t2 --network=na-br --ip 172.254.253.2 \
+    --volume "$PWD/src/tests/${TEST_NAME}/startNetconfAgent.sh:/confd/examples.confd/OC23/startNetconfAgent.sh" \
+    --volume "$PWD/src/tests/${TEST_NAME}/platform_t2.xml:/confd/examples.confd/OC23/init_openconfig-platform.xml" \
+    asgamb1/flexscale-hhi.img:latest /confd/examples.confd/OC23/startNetconfAgent.sh
+docker run -d --name na-r1 --network=na-br --ip 172.254.253.101 \
+    --volume "$PWD/src/tests/${TEST_NAME}/startNetconfAgent.sh:/confd/examples.confd/OC23/startNetconfAgent.sh" \
+    --volume "$PWD/src/tests/${TEST_NAME}/platform_r1.xml:/confd/examples.confd/OC23/init_openconfig-platform.xml" \
+    asgamb1/flexscale-node.img:latest /confd/examples.confd/OC23/startNetconfAgent.sh
+docker run -d --name na-r2 --network=na-br --ip 172.254.253.102 \
+    --volume "$PWD/src/tests/${TEST_NAME}/startNetconfAgent.sh:/confd/examples.confd/OC23/startNetconfAgent.sh" \
+    --volume "$PWD/src/tests/${TEST_NAME}/platform_r2.xml:/confd/examples.confd/OC23/init_openconfig-platform.xml" \
+    asgamb1/flexscale-node.img:latest /confd/examples.confd/OC23/startNetconfAgent.sh
+
+
+echo
+echo "Waiting for initialization..."
+echo "-----------------------------"
+docker ps -a
+sleep 5
+docker ps -a
+while ! docker logs na-t1 2>&1 | grep -q '*** ConfD OpenConfig NETCONF agent ***'; do sleep 1; done
+while ! docker logs na-t2 2>&1 | grep -q '*** ConfD OpenConfig NETCONF agent ***'; do sleep 1; done
+while ! docker logs na-r1 2>&1 | grep -q '*** ConfD OpenConfig NETCONF agent ***'; do sleep 1; done
+while ! docker logs na-r2 2>&1 | grep -q '*** ConfD OpenConfig NETCONF agent ***'; do sleep 1; done
+sleep 2
+docker ps -a
+
+
+echo
+echo "Dump Node Agent status:"
+echo "-----------------------"
+docker ps -a
+#docker logs na-t1
+#docker logs na-t2
+#docker logs na-r1
+#docker logs na-r2
+
+
+#echo
+#echo "Post-test clean-up:"
+#echo "-------------------"
+#docker rm -f na-t1 na-t2 na-r1 na-r2
+#docker network rm na-br
+
+echo "Done!"
diff --git a/src/tests/ofc24/deploy_specs.sh b/src/tests/ofc24/deploy_specs.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ca5494de25ea17c08c2df1f2d62923c59b0e81e2
--- /dev/null
+++ b/src/tests/ofc24/deploy_specs.sh
@@ -0,0 +1,163 @@
+#!/bin/bash
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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.
+
+
+# ----- TeraFlowSDN ------------------------------------------------------------
+
+# Set the URL of the internal MicroK8s Docker registry where the images will be uploaded to.
+export TFS_REGISTRY_IMAGES="http://localhost:32000/tfs/"
+
+# Set the list of components, separated by spaces, you want to build images for, and deploy.
+#export TFS_COMPONENTS="context device pathcomp service slice nbi webui load_generator"
+export TFS_COMPONENTS="context device pathcomp service slice nbi webui"
+
+# Uncomment to activate Monitoring
+#export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring"
+
+# Uncomment to activate BGP-LS Speaker
+#export TFS_COMPONENTS="${TFS_COMPONENTS} bgpls_speaker"
+
+# Uncomment to activate Optical Controller
+export TFS_COMPONENTS="${TFS_COMPONENTS} opticalcontroller"
+
+# Uncomment to activate ZTP
+#export TFS_COMPONENTS="${TFS_COMPONENTS} ztp"
+
+# Uncomment to activate Policy Manager
+#export TFS_COMPONENTS="${TFS_COMPONENTS} policy"
+
+# Uncomment to activate Optical CyberSecurity
+#export TFS_COMPONENTS="${TFS_COMPONENTS} dbscanserving opticalattackmitigator opticalattackdetector opticalattackmanager"
+
+# Uncomment to activate L3 CyberSecurity
+#export TFS_COMPONENTS="${TFS_COMPONENTS} l3_attackmitigator l3_centralizedattackdetector"
+
+# Uncomment to activate TE
+#export TFS_COMPONENTS="${TFS_COMPONENTS} te"
+
+# Uncomment to activate Forecaster
+#export TFS_COMPONENTS="${TFS_COMPONENTS} forecaster"
+
+# Uncomment to activate E2E Orchestrator
+#export TFS_COMPONENTS="${TFS_COMPONENTS} e2e_orchestrator"
+
+# Set the tag you want to use for your images.
+export TFS_IMAGE_TAG="dev"
+
+# Set the name of the Kubernetes namespace to deploy TFS to.
+export TFS_K8S_NAMESPACE="tfs"
+
+# Set additional manifest files to be applied after the deployment
+export TFS_EXTRA_MANIFESTS="manifests/nginx_ingress_http.yaml"
+
+# Uncomment to monitor performance of components
+export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/servicemonitors.yaml"
+
+# Uncomment when deploying Optical CyberSecurity
+#export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/cachingservice.yaml"
+
+# Set the new Grafana admin password
+export TFS_GRAFANA_PASSWORD="admin123+"
+
+# Disable skip-build flag to rebuild the Docker images.
+export TFS_SKIP_BUILD=""
+
+
+# ----- CockroachDB ------------------------------------------------------------
+
+# Set the namespace where CockroackDB will be deployed.
+export CRDB_NAMESPACE="crdb"
+
+# Set the external port CockroackDB Postgre SQL interface will be exposed to.
+export CRDB_EXT_PORT_SQL="26257"
+
+# Set the external port CockroackDB HTTP Mgmt GUI interface will be exposed to.
+export CRDB_EXT_PORT_HTTP="8081"
+
+# Set the database username to be used by Context.
+export CRDB_USERNAME="tfs"
+
+# Set the database user's password to be used by Context.
+export CRDB_PASSWORD="tfs123"
+
+# Set the database name to be used by Context.
+export CRDB_DATABASE="tfs"
+
+# Set CockroachDB installation mode to 'single'. This option is convenient for development and testing.
+# See ./deploy/all.sh or ./deploy/crdb.sh for additional details
+export CRDB_DEPLOY_MODE="single"
+
+# Disable flag for dropping database, if it exists.
+export CRDB_DROP_DATABASE_IF_EXISTS="YES"
+
+# Disable flag for re-deploying CockroachDB from scratch.
+export CRDB_REDEPLOY=""
+
+
+# ----- NATS -------------------------------------------------------------------
+
+# Set the namespace where NATS will be deployed.
+export NATS_NAMESPACE="nats"
+
+# Set the external port NATS Client interface will be exposed to.
+export NATS_EXT_PORT_CLIENT="4222"
+
+# Set the external port NATS HTTP Mgmt GUI interface will be exposed to.
+export NATS_EXT_PORT_HTTP="8222"
+
+# Disable flag for re-deploying NATS from scratch.
+export NATS_REDEPLOY=""
+
+
+# ----- QuestDB ----------------------------------------------------------------
+
+# Set the namespace where QuestDB will be deployed.
+export QDB_NAMESPACE="qdb"
+
+# Set the external port QuestDB Postgre SQL interface will be exposed to.
+export QDB_EXT_PORT_SQL="8812"
+
+# Set the external port QuestDB Influx Line Protocol interface will be exposed to.
+export QDB_EXT_PORT_ILP="9009"
+
+# Set the external port QuestDB HTTP Mgmt GUI interface will be exposed to.
+export QDB_EXT_PORT_HTTP="9000"
+
+# Set the database username to be used for QuestDB.
+export QDB_USERNAME="admin"
+
+# Set the database user's password to be used for QuestDB.
+export QDB_PASSWORD="quest"
+
+# Set the table name to be used by Monitoring for KPIs.
+export QDB_TABLE_MONITORING_KPIS="tfs_monitoring_kpis"
+
+# Set the table name to be used by Slice for plotting groups.
+export QDB_TABLE_SLICE_GROUPS="tfs_slice_groups"
+
+# Disable flag for dropping tables if they exist.
+export QDB_DROP_TABLES_IF_EXIST="YES"
+
+# Disable flag for re-deploying QuestDB from scratch.
+export QDB_REDEPLOY=""
+
+
+# ----- K8s Observability ------------------------------------------------------
+
+# Set the external port Prometheus Mgmt HTTP GUI interface will be exposed to.
+export PROM_EXT_PORT_HTTP="9090"
+
+# Set the external port Grafana HTTP Dashboards will be exposed to.
+export GRAF_EXT_PORT_HTTP="3000"
diff --git a/src/tests/ofc24/descriptors_topology.json b/src/tests/ofc24/descriptors_topology.json
new file mode 100644
index 0000000000000000000000000000000000000000..6ae521c7642b24d428b26b11c29882ca46995014
--- /dev/null
+++ b/src/tests/ofc24/descriptors_topology.json
@@ -0,0 +1,150 @@
+{
+    "contexts": [
+        {"context_id": {"context_uuid": {"uuid": "admin"}}}
+    ],
+    "topologies": [
+        {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}}
+    ],
+    "devices": [
+        {
+            "device_id": {"device_uuid": {"uuid": "T1"}}, "device_type": "optical-transponder", "device_drivers": [11],
+            "device_operational_status": 1,
+            "device_endpoints": [
+                {"endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "T1"}}, "endpoint_uuid": {"uuid": "1"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }}
+            ],
+            "device_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.15"}},
+                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "2023"}},
+                {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
+                    "username": "admin", "password": "admin", "force_running": false, "hostkey_verify": false,
+                    "look_for_keys": false, "allow_agent": false, "commit_per_rule": false,
+                    "device_params": {"name": "default"}, "manager_params": {"timeout": 120},
+                    "endpoints": [{"uuid": "1", "type": "optical", "sample_types": [101, 102, 201, 202]}]
+                }}}
+            ]}
+        },
+        {
+            "device_id": {"device_uuid": {"uuid": "T2"}}, "device_type": "optical-transponder", "device_drivers": [11],
+            "device_operational_status": 1,
+            "device_endpoints": [
+                {"endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "T2"}}, "endpoint_uuid": {"uuid": "6"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }}
+            ],
+            "device_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.15"}},
+                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "2024"}},
+                {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
+                    "username": "admin", "password": "admin", "force_running": false, "hostkey_verify": false,
+                    "look_for_keys": false, "allow_agent": false, "commit_per_rule": false,
+                    "device_params": {"name": "default"}, "manager_params": {"timeout": 120},
+                    "endpoints": [{"uuid": "6", "type": "optical", "sample_types": [101, 102, 201, 202]}]
+                }}}
+            ]}
+        },
+        {
+            "device_id": {"device_uuid": {"uuid": "R1"}}, "device_type": "optical-roadm", "device_drivers": [11],
+            "device_operational_status": 1,
+            "device_endpoints": [
+                {"endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "2"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }},
+                {"endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "3"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }},
+                {"endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "12"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }},
+                {"endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "13"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }}
+            ],
+            "device_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.15"}},
+                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "2025"}},
+                {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
+                    "username": "admin", "password": "admin", "force_running": false, "hostkey_verify": false,
+                    "look_for_keys": false, "allow_agent": false, "commit_per_rule": false,
+                    "device_params": {"name": "default"}, "manager_params": {"timeout": 120},
+                    "endpoints": [
+                        {"sample_types": [101, 102, 201, 202], "type": "optical", "uuid": "2"},
+                        {"sample_types": [101, 102, 201, 202], "type": "optical", "uuid": "3"},
+                        {"sample_types": [101, 102, 201, 202], "type": "optical", "uuid": "12"},
+                        {"sample_types": [101, 102, 201, 202], "type": "optical", "uuid": "13"}
+                    ]}
+                }}]
+            }
+        },
+        {
+            "device_id": {"device_uuid": {"uuid": "R2"}}, "device_type": "optical-roadm", "device_drivers": [11],
+            "device_operational_status": 1,
+            "device_endpoints": [
+                {"endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "4"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }},
+                {"endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "5"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }},
+                {"endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "14"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }},
+                {"endpoint_id": {
+                    "device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "15"},
+                    "topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}
+                }}
+            ],
+            "device_config": {"config_rules": [
+                {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.15"}},
+                {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "2026"}},
+                {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {
+                    "username": "admin", "password": "admin", "force_running": false, "hostkey_verify": false,
+                    "look_for_keys": false, "allow_agent": false, "commit_per_rule": false,
+                    "device_params": {"name": "default"}, "manager_params": {"timeout": 120},
+                    "endpoints": [
+                        {"sample_types": [101, 102, 201, 202], "type": "optical", "uuid": "4"},
+                        {"sample_types": [101, 102, 201, 202], "type": "optical", "uuid": "5"},
+                        {"sample_types": [101, 102, 201, 202], "type": "optical", "uuid": "14"},
+                        {"sample_types": [101, 102, 201, 202], "type": "optical", "uuid": "15"}
+                    ]
+                }}}
+            ]}
+        }
+    ],
+    "links": [
+        {"link_id": {"link_uuid": {"uuid": "T1->R1"}}, "link_endpoint_ids": [
+            {"device_id": {"device_uuid": {"uuid": "T1"}}, "endpoint_uuid": {"uuid": "1"}},
+            {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "12"}}
+        ]},
+        {"link_id": {"link_uuid": {"uuid": "R1->T1"}}, "link_endpoint_ids": [
+            {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "2"}},
+            {"device_id": {"device_uuid": {"uuid": "T1"}}, "endpoint_uuid": {"uuid": "1"}}
+        ]},
+        {"link_id": {"link_uuid": {"uuid": "R1->R2"}}, "link_endpoint_ids": [
+            {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "3"}},
+            {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "14"}}
+        ]},
+        {"link_id": {"link_uuid": {"uuid": "R2->R1"}}, "link_endpoint_ids": [
+            {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "4"}},
+            {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "13"}}
+        ]},
+        {"link_id": {"link_uuid": {"uuid": "T2->R2"}}, "link_endpoint_ids": [
+            {"device_id": {"device_uuid": {"uuid": "T2"}}, "endpoint_uuid": {"uuid": "6"}},
+            {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "15"}}
+        ]},
+        {"link_id": {"link_uuid": {"uuid": "R2->T2"}}, "link_endpoint_ids": [
+            {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "5"}},
+            {"device_id": {"device_uuid": {"uuid": "T2"}}, "endpoint_uuid": {"uuid": "6"}}
+        ]}
+    ]
+}
diff --git a/src/tests/ofc24/plat_r1.xml b/src/tests/ofc24/platform_r1.xml
similarity index 99%
rename from src/tests/ofc24/plat_r1.xml
rename to src/tests/ofc24/platform_r1.xml
index 47e135c2e3752de21dbe2f17550026e9622f4de1..625d7048a8062698b67db92f94f5d17c73dda0f4 100755
--- a/src/tests/ofc24/plat_r1.xml
+++ b/src/tests/ofc24/platform_r1.xml
@@ -117,4 +117,4 @@
             </properties>
         </component>
     </components>
-</config>
\ No newline at end of file
+</config>
diff --git a/src/tests/ofc24/plat_r2.xml b/src/tests/ofc24/platform_r2.xml
similarity index 99%
rename from src/tests/ofc24/plat_r2.xml
rename to src/tests/ofc24/platform_r2.xml
index dfaaf05ad7134a950ec11f411037b9a058b7d719..65f7ee45866b792bac06473d7a59f83eab4c8f54 100755
--- a/src/tests/ofc24/plat_r2.xml
+++ b/src/tests/ofc24/platform_r2.xml
@@ -117,4 +117,4 @@
             </properties>
         </component>
     </components>
-</config>
\ No newline at end of file
+</config>
diff --git a/src/tests/ofc24/platform_t1.xml b/src/tests/ofc24/platform_t1.xml
new file mode 100755
index 0000000000000000000000000000000000000000..09f316211dcd5fce4a31de45065bddb276c5b268
--- /dev/null
+++ b/src/tests/ofc24/platform_t1.xml
@@ -0,0 +1,295 @@
+<config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
+	<components xmlns="http://openconfig.net/yang/platform">
+		<component>
+			<name>device</name>
+			<config>
+				<name>device</name>
+			</config>
+			<state>
+				<name>MellanoxSwitch</name>
+				<mfg-name>SSSA-CNIT</mfg-name>
+				<hardware-version>1.0.0</hardware-version>
+				<firmware-version>1.0.0</firmware-version>
+				<software-version>1.0.0</software-version>
+				<serial-no>610610</serial-no>
+				<type xmlns:typex="http://openconfig.net/yang/platform-types">typex:OPERATING_SYSTEM</type>
+			</state>
+		</component>
+		<component>
+			<name>channel-1</name>
+			<config>
+				<name>channel-1</name>
+			</config>
+			<state>
+				<name>channel-1</name>
+				<type xmlns:typex="http://openconfig.net/yang/transport-types">typex:OPTICAL_CHANNEL</type>
+			</state>
+			<optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+				<config>
+					<frequency>191600000</frequency>
+					<target-output-power>100</target-output-power>
+					<operational-mode>0</operational-mode>
+					<line-port>transceiver-1</line-port>
+				</config>
+				<state>
+					<frequency>191600000</frequency>
+					<target-output-power>0</target-output-power>
+					<operational-mode>0</operational-mode>
+					<line-port>transceiver-1</line-port>
+					<group-id>1</group-id>
+					<output-power>
+						<instant>0</instant>
+						<avg>0</avg>
+						<min>0</min>
+						<max>0</max>
+						<interval>0</interval>
+					</output-power>
+					<input-power>
+						<instant>0</instant>
+						<avg>0</avg>
+						<min>0</min>
+						<max>0</max>
+						<interval>0</interval>
+					</input-power>
+					<laser-bias-current>
+						<instant>0</instant>
+						<avg>0</avg>
+						<min>0</min>
+						<max>0</max>
+						<interval>0</interval>
+					</laser-bias-current>
+					<chromatic-dispersion>
+						<instant>0</instant>
+						<avg>0</avg>
+						<min>0</min>
+						<max>0</max>
+					</chromatic-dispersion>
+					<polarization-mode-dispersion>
+						<instant>0</instant>
+						<avg>0</avg>
+						<min>0</min>
+						<max>0</max>
+					</polarization-mode-dispersion>
+					<second-order-polarization-mode-dispersion>
+						<instant>0</instant>
+						<avg>0</avg>
+						<min>0</min>
+						<max>0</max>
+					</second-order-polarization-mode-dispersion>
+					<polarization-dependent-loss>
+						<instant>0</instant>
+						<avg>0</avg>
+						<min>0</min>
+						<max>0</max>
+						<interval>0</interval>
+					</polarization-dependent-loss>
+				</state>
+			</optical-channel>
+		</component>
+		<component>
+			<name>transceiver-1</name>
+			<config>
+				<name>transceiver-1</name>
+			</config>
+			<state>
+				<name>transceiver-1</name>
+				<type xmlns:typex="http://openconfig.net/yang/platform-types">typex:TRANSCEIVER</type>
+			</state>
+			<transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+				<config>
+					<enabled>true</enabled>
+					<form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf>
+					<ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf>
+					<fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode>
+					<module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type>
+				</config>
+				<state>
+					<enabled>true</enabled>
+					<form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf>
+					<ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf>
+					<fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode>
+					<module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type>
+					<vendor>Cisco</vendor>
+					<vendor-part>400zr-QSFP-DD</vendor-part>
+					<vendor-rev>01</vendor-rev>
+					<serial-no>1567321</serial-no>
+				</state>
+				<physical-channels>
+					<channel>
+						<index>1</index>
+						<config>
+							<index>1</index>
+							<associated-optical-channel>channel-1</associated-optical-channel>
+						</config>
+						<!--state>
+							<index>1</index>
+							<associated-optical-channel>channel-4</associated-optical-channel>
+						</state-->
+					</channel>
+				</physical-channels>
+			</transceiver>
+		</component>
+		<component>
+			<name>port-1</name>
+			<config>
+				<name>port-1</name>
+			</config>
+			<state>
+				<name>port-1</name>
+				<type xmlns:typex="http://openconfig.net/yang/platform-types">typex:PORT</type>
+			</state>
+			<subcomponents>
+				<subcomponent>
+					<name>channel-1</name>
+					<config>
+						<name>channel-1</name>
+					</config>
+					<state>
+						<name>channel-1</name>
+					</state>
+				</subcomponent>
+			</subcomponents>
+			<properties>
+				<property>
+					<name>onos-index</name>
+					<config>
+						<name>onos-index</name>
+						<value>4</value>
+					</config>
+					<state>
+						<name>onos-index</name>
+						<value>4</value>
+					</state>
+				</property>
+				<property>
+					<name>odtn-port-type</name>
+					<config>
+						<name>odtn-port-type</name>
+						<value>line</value>
+					</config>
+					<state>
+						<name>odtn-port-type</name>
+						<value>line</value>
+					</state>
+				</property>
+			</properties>
+		</component>
+	</components>
+	<terminal-device xmlns="http://openconfig.net/yang/terminal-device">
+		<logical-channels>
+			<!--Description: Optical logical link-->
+			<channel>
+
+				<!--Description: Line (OTN) Port-->
+				<index>1</index>
+				<config>
+					<index>1</index>
+					<description>Logical channel 1</description>
+					<admin-state>DISABLED</admin-state>
+					<logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type>
+					<loopback-mode>NONE</loopback-mode>
+				</config>
+				<state>
+					<index>1</index>
+					<description>Logical channel 1</description>
+					<admin-state>DISABLED</admin-state>
+					<logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type>
+					<loopback-mode>NONE</loopback-mode>
+					<link-state>UP</link-state>
+				</state>
+				<ingress>
+					<config>
+						<transceiver>transceiver-1</transceiver>
+					</config>
+					<state>
+						<transceiver>transceiver-1</transceiver>
+					</state>
+				</ingress>
+				<otn>
+					<config>
+						<tti-msg-expected>test1</tti-msg-expected>
+						<tti-msg-transmit>test1</tti-msg-transmit>
+					</config>
+					<state>
+						<tti-msg-expected>test1</tti-msg-expected>
+						<tti-msg-transmit>test1</tti-msg-transmit>
+						<tti-msg-auto>0</tti-msg-auto>
+						<tti-msg-recv>0</tti-msg-recv>
+						<rdi-msg>0</rdi-msg>
+						<errored-seconds>0</errored-seconds>
+						<severely-errored-seconds>0</severely-errored-seconds>
+						<unavailable-seconds>0</unavailable-seconds>
+						<code-violations>0</code-violations>
+						<fec-uncorrectable-words>0</fec-uncorrectable-words>
+						<fec-corrected-bytes>0</fec-corrected-bytes>
+						<fec-corrected-bits>0</fec-corrected-bits>
+						<background-block-errors>0</background-block-errors>
+						<pre-fec-ber>
+							<instant>0.0</instant>
+							<avg>0.0</avg>
+							<min>0.0</min>
+							<max>0.0</max>
+						</pre-fec-ber>
+						<post-fec-ber>
+							<instant>0.0</instant>
+							<avg>0.0</avg>
+							<min>0.0</min>
+							<max>0.0</max>
+						</post-fec-ber>
+						<q-value>
+							<instant>0.0</instant>
+							<avg>0.0</avg>
+							<min>0.0</min>
+							<max>0.0</max>
+							<interval>0</interval>
+						</q-value>
+						<esnr>
+							<instant>0.0</instant>
+							<avg>0.0</avg>
+							<min>0.0</min>
+							<max>0.0</max>
+							<interval>0</interval>
+						</esnr>
+					</state>
+				</otn>
+				<logical-channel-assignments>
+					<assignment>
+						<index>1</index>
+						<config>
+							<index>1</index>
+							<description>Optical channel assigned 100</description>
+							<allocation>100</allocation>
+							<assignment-type>OPTICAL_CHANNEL</assignment-type>
+							<optical-channel>channel-1</optical-channel>
+						</config>
+						<state>
+							<index>1</index>
+							<description>Optical channel assigned 100</description>
+							<allocation>100</allocation>
+							<assignment-type>OPTICAL_CHANNEL</assignment-type>
+							<optical-channel>channel-1</optical-channel>
+						</state>
+					</assignment>
+				</logical-channel-assignments>
+			</channel>
+		</logical-channels>
+		<operational-modes>
+			<mode>
+				<mode-id>1</mode-id>
+				<state>
+					<mode-id>1</mode-id>
+					<description>FEC1</description>
+					<vendor-id>Ericsson</vendor-id>
+				</state>
+			</mode>
+			<mode>
+				<mode-id>2</mode-id>
+				<state>
+					<mode-id>2</mode-id>
+					<description>FEC2</description>
+					<vendor-id>Ericsson</vendor-id>
+				</state>
+			</mode>
+		</operational-modes>
+	</terminal-device>
+</config>
diff --git a/src/tests/ofc24/platform_t2.xml b/src/tests/ofc24/platform_t2.xml
new file mode 100755
index 0000000000000000000000000000000000000000..03c643c91f176b531ec25bda6fbb36c8bdb1c099
--- /dev/null
+++ b/src/tests/ofc24/platform_t2.xml
@@ -0,0 +1,295 @@
+<config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
+	<components xmlns="http://openconfig.net/yang/platform">
+		<component>
+			<name>device</name>
+			<config>
+				<name>device</name>
+			</config>
+			<state>
+				<name>MellanoxSwitch</name>
+				<mfg-name>SSSA-CNIT</mfg-name>
+				<hardware-version>1.0.0</hardware-version>
+				<firmware-version>1.0.0</firmware-version>
+				<software-version>1.0.0</software-version>
+				<serial-no>610610</serial-no>
+				<type xmlns:typex="http://openconfig.net/yang/platform-types">typex:OPERATING_SYSTEM</type>
+			</state>
+		</component>
+		<component>
+			<name>channel-6</name>
+			<config>
+				<name>channel-6</name>
+			</config>
+			<state>
+				<name>channel-6</name>
+				<type xmlns:typex="http://openconfig.net/yang/transport-types">typex:OPTICAL_CHANNEL</type>
+			</state>
+			<optical-channel xmlns="http://openconfig.net/yang/terminal-device">
+				<config>
+					<frequency>191600000</frequency>
+					<target-output-power>100</target-output-power>
+					<operational-mode>0</operational-mode>
+					<line-port>transceiver-6</line-port>
+				</config>
+				<state>
+					<frequency>191600000</frequency>
+					<target-output-power>0</target-output-power>
+					<operational-mode>0</operational-mode>
+					<line-port>transceiver-6</line-port>
+					<group-id>1</group-id>
+					<output-power>
+						<instant>0</instant>
+						<avg>0</avg>
+						<min>0</min>
+						<max>0</max>
+						<interval>0</interval>
+					</output-power>
+					<input-power>
+						<instant>0</instant>
+						<avg>0</avg>
+						<min>0</min>
+						<max>0</max>
+						<interval>0</interval>
+					</input-power>
+					<laser-bias-current>
+						<instant>0</instant>
+						<avg>0</avg>
+						<min>0</min>
+						<max>0</max>
+						<interval>0</interval>
+					</laser-bias-current>
+					<chromatic-dispersion>
+						<instant>0</instant>
+						<avg>0</avg>
+						<min>0</min>
+						<max>0</max>
+					</chromatic-dispersion>
+					<polarization-mode-dispersion>
+						<instant>0</instant>
+						<avg>0</avg>
+						<min>0</min>
+						<max>0</max>
+					</polarization-mode-dispersion>
+					<second-order-polarization-mode-dispersion>
+						<instant>0</instant>
+						<avg>0</avg>
+						<min>0</min>
+						<max>0</max>
+					</second-order-polarization-mode-dispersion>
+					<polarization-dependent-loss>
+						<instant>0</instant>
+						<avg>0</avg>
+						<min>0</min>
+						<max>0</max>
+						<interval>0</interval>
+					</polarization-dependent-loss>
+				</state>
+			</optical-channel>
+		</component>
+		<component>
+			<name>transceiver-6</name>
+			<config>
+				<name>transceiver-6</name>
+			</config>
+			<state>
+				<name>transceiver-6</name>
+				<type xmlns:typex="http://openconfig.net/yang/platform-types">typex:TRANSCEIVER</type>
+			</state>
+			<transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
+				<config>
+					<enabled>true</enabled>
+					<form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf>
+					<ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf>
+					<fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode>
+					<module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type>
+				</config>
+				<state>
+					<enabled>true</enabled>
+					<form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf>
+					<ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf>
+					<fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode>
+					<module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type>
+					<vendor>Cisco</vendor>
+					<vendor-part>400zr-QSFP-DD</vendor-part>
+					<vendor-rev>01</vendor-rev>
+					<serial-no>1567321</serial-no>
+				</state>
+				<physical-channels>
+					<channel>
+						<index>1</index>
+						<config>
+							<index>1</index>
+							<associated-optical-channel>channel-6</associated-optical-channel>
+						</config>
+						<!--state>
+							<index>1</index>
+							<associated-optical-channel>channel-4</associated-optical-channel>
+						</state-->
+					</channel>
+				</physical-channels>
+			</transceiver>
+		</component>
+		<component>
+			<name>port-6</name>
+			<config>
+				<name>port-6</name>
+			</config>
+			<state>
+				<name>port-6</name>
+				<type xmlns:typex="http://openconfig.net/yang/platform-types">typex:PORT</type>
+			</state>
+			<subcomponents>
+				<subcomponent>
+					<name>channel-6</name>
+					<config>
+						<name>channel-6</name>
+					</config>
+					<state>
+						<name>channel-6</name>
+					</state>
+				</subcomponent>
+			</subcomponents>
+			<properties>
+				<property>
+					<name>onos-index</name>
+					<config>
+						<name>onos-index</name>
+						<value>4</value>
+					</config>
+					<state>
+						<name>onos-index</name>
+						<value>4</value>
+					</state>
+				</property>
+				<property>
+					<name>odtn-port-type</name>
+					<config>
+						<name>odtn-port-type</name>
+						<value>line</value>
+					</config>
+					<state>
+						<name>odtn-port-type</name>
+						<value>line</value>
+					</state>
+				</property>
+			</properties>
+		</component>
+	</components>
+	<terminal-device xmlns="http://openconfig.net/yang/terminal-device">
+		<logical-channels>
+			<!--Description: Optical logical link-->
+			<channel>
+
+				<!--Description: Line (OTN) Port-->
+				<index>4</index>
+				<config>
+					<index>4</index>
+					<description>Logical channel 4</description>
+					<admin-state>DISABLED</admin-state>
+					<logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type>
+					<loopback-mode>NONE</loopback-mode>
+				</config>
+				<state>
+					<index>4</index>
+					<description>Logical channel 4</description>
+					<admin-state>DISABLED</admin-state>
+					<logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type>
+					<loopback-mode>NONE</loopback-mode>
+					<link-state>UP</link-state>
+				</state>
+				<ingress>
+					<config>
+						<transceiver>transceiver-6</transceiver>
+					</config>
+					<state>
+						<transceiver>transceiver-6</transceiver>
+					</state>
+				</ingress>
+				<otn>
+					<config>
+						<tti-msg-expected>test1</tti-msg-expected>
+						<tti-msg-transmit>test1</tti-msg-transmit>
+					</config>
+					<state>
+						<tti-msg-expected>test1</tti-msg-expected>
+						<tti-msg-transmit>test1</tti-msg-transmit>
+						<tti-msg-auto>0</tti-msg-auto>
+						<tti-msg-recv>0</tti-msg-recv>
+						<rdi-msg>0</rdi-msg>
+						<errored-seconds>0</errored-seconds>
+						<severely-errored-seconds>0</severely-errored-seconds>
+						<unavailable-seconds>0</unavailable-seconds>
+						<code-violations>0</code-violations>
+						<fec-uncorrectable-words>0</fec-uncorrectable-words>
+						<fec-corrected-bytes>0</fec-corrected-bytes>
+						<fec-corrected-bits>0</fec-corrected-bits>
+						<background-block-errors>0</background-block-errors>
+						<pre-fec-ber>
+							<instant>0.0</instant>
+							<avg>0.0</avg>
+							<min>0.0</min>
+							<max>0.0</max>
+						</pre-fec-ber>
+						<post-fec-ber>
+							<instant>0.0</instant>
+							<avg>0.0</avg>
+							<min>0.0</min>
+							<max>0.0</max>
+						</post-fec-ber>
+						<q-value>
+							<instant>0.0</instant>
+							<avg>0.0</avg>
+							<min>0.0</min>
+							<max>0.0</max>
+							<interval>0</interval>
+						</q-value>
+						<esnr>
+							<instant>0.0</instant>
+							<avg>0.0</avg>
+							<min>0.0</min>
+							<max>0.0</max>
+							<interval>0</interval>
+						</esnr>
+					</state>
+				</otn>
+				<logical-channel-assignments>
+					<assignment>
+						<index>1</index>
+						<config>
+							<index>1</index>
+							<description>Optical channel assigned 100</description>
+							<allocation>100</allocation>
+							<assignment-type>OPTICAL_CHANNEL</assignment-type>
+							<optical-channel>channel-6</optical-channel>
+						</config>
+						<state>
+							<index>1</index>
+							<description>Optical channel assigned 100</description>
+							<allocation>100</allocation>
+							<assignment-type>OPTICAL_CHANNEL</assignment-type>
+							<optical-channel>channel-6</optical-channel>
+						</state>
+					</assignment>
+				</logical-channel-assignments>
+			</channel>
+		</logical-channels>
+		<operational-modes>
+			<mode>
+				<mode-id>1</mode-id>
+				<state>
+					<mode-id>1</mode-id>
+					<description>FEC1</description>
+					<vendor-id>Ericsson</vendor-id>
+				</state>
+			</mode>
+			<mode>
+				<mode-id>2</mode-id>
+				<state>
+					<mode-id>2</mode-id>
+					<description>FEC2</description>
+					<vendor-id>Ericsson</vendor-id>
+				</state>
+			</mode>
+		</operational-modes>
+	</terminal-device>
+</config>
diff --git a/src/tests/ofc24/requirements.in b/src/tests/ofc24/requirements.in
new file mode 100644
index 0000000000000000000000000000000000000000..30b11e65301a7bfc3ae89bf77e5e2734b0f3b566
--- /dev/null
+++ b/src/tests/ofc24/requirements.in
@@ -0,0 +1,15 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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.
+
+requests==2.27.*
diff --git a/src/tests/ofc24/startNetconfAgent.sh b/src/tests/ofc24/startNetconfAgent.sh
new file mode 100755
index 0000000000000000000000000000000000000000..10b721883799c4fd257e1f627ff1480259037702
--- /dev/null
+++ b/src/tests/ofc24/startNetconfAgent.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+make clean
+make all
+#make init
+cp init_openconfig-platform.xml confd-cdb/
+#cp init_flex-scale-mg-on.xml confd-cdb/
+make start2
diff --git a/src/tests/ofc24/t1.xml b/src/tests/ofc24/t1.xml
deleted file mode 100755
index 712615df8dd821ff8e79df9785d6d29324a25b7d..0000000000000000000000000000000000000000
--- a/src/tests/ofc24/t1.xml
+++ /dev/null
@@ -1,298 +0,0 @@
-<config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <components xmlns="http://openconfig.net/yang/platform">
-        <component>
-            <name>device</name>
-            <config>
-                <name>device</name>
-            </config>
-            <state>
-				<name>MellanoxSwitch</name>
-				<mfg-name>SSSA-CNIT</mfg-name>
-				<hardware-version>1.0.0</hardware-version>
-				<firmware-version>1.0.0</firmware-version>
-				<software-version>1.0.0</software-version>
-				<serial-no>610610</serial-no>
-				<type xmlns:typex="http://openconfig.net/yang/platform-types">typex:OPERATING_SYSTEM</type>
-			</state>
-		</component>
-		<component>
-			<name>channel-1</name>
-			<config>
-					<name>channel-1</name>
-			</config>
-			<state>
-				<name>channel-1</name>
-				<type xmlns:typex="http://openconfig.net/yang/transport-types">typex:OPTICAL_CHANNEL</type>
-			</state>
-			<optical-channel xmlns="http://openconfig.net/yang/terminal-device">
-				<config>
-					<frequency>191600000</frequency>
-					<target-output-power>100</target-output-power>
-					<operational-mode>0</operational-mode>
-					<line-port>transceiver-1</line-port>
-				</config>
-				<state>
-					<frequency>191600000</frequency>
-					<target-output-power>0</target-output-power>
-					<operational-mode>0</operational-mode>
-					<line-port>transceiver-1</line-port>
-					<group-id>1</group-id>
-					<output-power>
-						<instant>0</instant>
-						<avg>0</avg>
-						<min>0</min>
-						<max>0</max>
-						<interval>0</interval>
-					</output-power>
-					<input-power>
-						<instant>0</instant>
-						<avg>0</avg>
-						<min>0</min>
-						<max>0</max>
-						<interval>0</interval>
-					</input-power>
-					<laser-bias-current>
-						<instant>0</instant>
-						<avg>0</avg>
-						<min>0</min>
-						<max>0</max>
-						<interval>0</interval>
-					</laser-bias-current>
-					<chromatic-dispersion>
-						<instant>0</instant>
-						<avg>0</avg>
-						<min>0</min>
-						<max>0</max>
-					</chromatic-dispersion>
-					<polarization-mode-dispersion>
-						<instant>0</instant>
-						<avg>0</avg>
-						<min>0</min>
-						<max>0</max>
-					</polarization-mode-dispersion>
-					<second-order-polarization-mode-dispersion>
-						<instant>0</instant>
-						<avg>0</avg>
-						<min>0</min>
-						<max>0</max>
-					</second-order-polarization-mode-dispersion>
-					<polarization-dependent-loss>
-						<instant>0</instant>
-						<avg>0</avg>
-						<min>0</min>
-						<max>0</max>
-						<interval>0</interval>
-					</polarization-dependent-loss>
-				</state>
-			</optical-channel>
-		</component>
-		<component>
-			<name>transceiver-1</name>
-			<config>
-				<name>transceiver-1</name>
-			</config>
-			<state>
-				<name>transceiver-1</name>
-				<type xmlns:typex="http://openconfig.net/yang/platform-types">typex:TRANSCEIVER</type>
-			</state>
-			<transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
-				<config>
-					<enabled>true</enabled>
-					<form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf>
-					<ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf>
-					<fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode>
-					<module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type>
-				</config>
-				<state>
-					<enabled>true</enabled>
-					<form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf>
-					<ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf>
-					<fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode>
-					<module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type>
-					<vendor>Cisco</vendor>
-					<vendor-part>400zr-QSFP-DD</vendor-part>
-					<vendor-rev>01</vendor-rev>
-					<serial-no>1567321</serial-no>
-				</state>
-				<physical-channels>
-					<channel>
-						<index>1</index>
-						<config>
-							<index>1</index>
-							<associated-optical-channel>channel-1</associated-optical-channel>
-						</config>
-						<!--state>
-							<index>1</index>
-							<associated-optical-channel>channel-4</associated-optical-channel>
-						</state-->
-					</channel>
-				</physical-channels>
-			</transceiver>
-		</component>
-    <component>
-                        <name>port-1</name>
-                        <config>
-                                <name>port-1</name>
-                        </config>
-                        <state>
-                                <name>port-1</name>
-                        <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:PORT</type>
-                        </state>
-                        <subcomponents>
-                                <subcomponent>
-                                        <name>channel-1</name>
-                                        <config>
-                                                <name>channel-1</name>
-                                        </config>
-                                        <state>
-                                                <name>channel-1</name>
-                                        </state>
-                                </subcomponent>
-                        </subcomponents>
-                        <properties>
-                                <property>
-                                        <name>onos-index</name>
-                                        <config>
-                                                <name>onos-index</name>
-                                                <value>4</value>
-                                        </config>
-                                        <state>
-                                                <name>onos-index</name>
-                                                <value>4</value>
-                                        </state>
-                                </property>
-                                <property>
-                                        <name>odtn-port-type</name>
-                                        <config>
-                                                <name>odtn-port-type</name>
-                                                <value>line</value>
-                                        </config>
-                                        <state>
-                                                <name>odtn-port-type</name>
-                                                <value>line</value>
-                                        </state>
-                                </property>
-                        </properties>
-                </component>
-
-   
-	</components>
-	<terminal-device xmlns="http://openconfig.net/yang/terminal-device">
-             <logical-channels>
-                  <!--Description: Optical logical link-->
-                  <channel>
-
-			<!--Description: Line (OTN) Port-->
-			<index>1</index>
-			<config>
-				<index>1</index>
-				<description>Logical channel 1</description>
-				<admin-state>DISABLED</admin-state>
-				<logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type>
-				<loopback-mode>NONE</loopback-mode>
-			</config>
-			<state>
-				<index>1</index>
-				<description>Logical channel 1</description>
-				<admin-state>DISABLED</admin-state>
-				<logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type>
-				<loopback-mode>NONE</loopback-mode>
-				<link-state>UP</link-state>
-			</state>
-		   	<ingress>
-				<config>
-					<transceiver>transceiver-1</transceiver>
-				</config>
-				<state>
-					<transceiver>transceiver-1</transceiver>
-				</state>
-			</ingress>
-			<otn>
-				<config>
-					<tti-msg-expected>test1</tti-msg-expected>
-					<tti-msg-transmit>test1</tti-msg-transmit>
-				</config>
-				<state>
-					<tti-msg-expected>test1</tti-msg-expected>
-					<tti-msg-transmit>test1</tti-msg-transmit>
-					<tti-msg-auto>0</tti-msg-auto>
-					<tti-msg-recv>0</tti-msg-recv>
-					<rdi-msg>0</rdi-msg>
-					<errored-seconds>0</errored-seconds>
-					<severely-errored-seconds>0</severely-errored-seconds>
-					<unavailable-seconds>0</unavailable-seconds>
-					<code-violations>0</code-violations>
-					<fec-uncorrectable-words>0</fec-uncorrectable-words>
-					<fec-corrected-bytes>0</fec-corrected-bytes>
-					<fec-corrected-bits>0</fec-corrected-bits>
-					<background-block-errors>0</background-block-errors>
-					<pre-fec-ber>
-						<instant>0.0</instant>
-						<avg>0.0</avg>
-						<min>0.0</min>
-						<max>0.0</max>
-					</pre-fec-ber>
-					<post-fec-ber>
-						<instant>0.0</instant>
-						<avg>0.0</avg>
-						<min>0.0</min>
-						<max>0.0</max>
-					</post-fec-ber>
-					<q-value>
-						<instant>0.0</instant>
-						<avg>0.0</avg>
-						<min>0.0</min>
-						<max>0.0</max>
-						<interval>0</interval>
-					</q-value>
-					<esnr>
-						<instant>0.0</instant>
-						<avg>0.0</avg>
-						<min>0.0</min>
-						<max>0.0</max>
-						<interval>0</interval>
-					</esnr>
-				</state>
-			</otn>
-			<logical-channel-assignments>
-				<assignment>
-					<index>1</index>
-					<config>
-							<index>1</index>
-							<description>Optical channel assigned 100</description>
-							<allocation>100</allocation>
-							<assignment-type>OPTICAL_CHANNEL</assignment-type>
-							<optical-channel>channel-1</optical-channel>
-					</config>
-					<state>
-							<index>1</index>
-							<description>Optical channel assigned 100</description>
-							<allocation>100</allocation>
-							<assignment-type>OPTICAL_CHANNEL</assignment-type>
-							<optical-channel>channel-1</optical-channel>
-					</state>
-				</assignment>
-			</logical-channel-assignments>
-                  </channel>
-           </logical-channels>
-    	   <operational-modes>
-           <mode>
-	   	<mode-id>1</mode-id>
-			<state>
-				<mode-id>1</mode-id>
-				<description>FEC1</description>
-				<vendor-id>Ericsson</vendor-id>
-			</state>
-		</mode>
-		<mode>
-		    <mode-id>2</mode-id>
-			<state>
-				<mode-id>2</mode-id>
-				<description>FEC2</description>
-				<vendor-id>Ericsson</vendor-id>
-			</state>
-		</mode>		
-    	   </operational-modes>
-	</terminal-device>
-</config>
-
diff --git a/src/tests/ofc24/t2.xml b/src/tests/ofc24/t2.xml
deleted file mode 100755
index 3a35e7e87eac7b14cd2bfa693560cc653f3719b9..0000000000000000000000000000000000000000
--- a/src/tests/ofc24/t2.xml
+++ /dev/null
@@ -1,298 +0,0 @@
-<config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
-    <components xmlns="http://openconfig.net/yang/platform">
-        <component>
-            <name>device</name>
-            <config>
-                <name>device</name>
-            </config>
-            <state>
-				<name>MellanoxSwitch</name>
-				<mfg-name>SSSA-CNIT</mfg-name>
-				<hardware-version>1.0.0</hardware-version>
-				<firmware-version>1.0.0</firmware-version>
-				<software-version>1.0.0</software-version>
-				<serial-no>610610</serial-no>
-				<type xmlns:typex="http://openconfig.net/yang/platform-types">typex:OPERATING_SYSTEM</type>
-			</state>
-		</component>
-		<component>
-			<name>channel-6</name>
-			<config>
-					<name>channel-6</name>
-			</config>
-			<state>
-				<name>channel-6</name>
-				<type xmlns:typex="http://openconfig.net/yang/transport-types">typex:OPTICAL_CHANNEL</type>
-			</state>
-			<optical-channel xmlns="http://openconfig.net/yang/terminal-device">
-				<config>
-					<frequency>191600000</frequency>
-					<target-output-power>100</target-output-power>
-					<operational-mode>0</operational-mode>
-					<line-port>transceiver-6</line-port>
-				</config>
-				<state>
-					<frequency>191600000</frequency>
-					<target-output-power>0</target-output-power>
-					<operational-mode>0</operational-mode>
-					<line-port>transceiver-6</line-port>
-					<group-id>1</group-id>
-					<output-power>
-						<instant>0</instant>
-						<avg>0</avg>
-						<min>0</min>
-						<max>0</max>
-						<interval>0</interval>
-					</output-power>
-					<input-power>
-						<instant>0</instant>
-						<avg>0</avg>
-						<min>0</min>
-						<max>0</max>
-						<interval>0</interval>
-					</input-power>
-					<laser-bias-current>
-						<instant>0</instant>
-						<avg>0</avg>
-						<min>0</min>
-						<max>0</max>
-						<interval>0</interval>
-					</laser-bias-current>
-					<chromatic-dispersion>
-						<instant>0</instant>
-						<avg>0</avg>
-						<min>0</min>
-						<max>0</max>
-					</chromatic-dispersion>
-					<polarization-mode-dispersion>
-						<instant>0</instant>
-						<avg>0</avg>
-						<min>0</min>
-						<max>0</max>
-					</polarization-mode-dispersion>
-					<second-order-polarization-mode-dispersion>
-						<instant>0</instant>
-						<avg>0</avg>
-						<min>0</min>
-						<max>0</max>
-					</second-order-polarization-mode-dispersion>
-					<polarization-dependent-loss>
-						<instant>0</instant>
-						<avg>0</avg>
-						<min>0</min>
-						<max>0</max>
-						<interval>0</interval>
-					</polarization-dependent-loss>
-				</state>
-			</optical-channel>
-		</component>
-		<component>
-			<name>transceiver-6</name>
-			<config>
-				<name>transceiver-6</name>
-			</config>
-			<state>
-				<name>transceiver-6</name>
-				<type xmlns:typex="http://openconfig.net/yang/platform-types">typex:TRANSCEIVER</type>
-			</state>
-			<transceiver xmlns="http://openconfig.net/yang/platform/transceiver">
-				<config>
-					<enabled>true</enabled>
-					<form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf>
-					<ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf>
-					<fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode>
-					<module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type>
-				</config>
-				<state>
-					<enabled>true</enabled>
-					<form-factor-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:QSFP56_DD_TYPE1</form-factor-preconf>
-					<ethernet-pmd-preconf xmlns:typex="http://openconfig.net/yang/transport-types">typex:ETH_400GBASE_ZR</ethernet-pmd-preconf>
-					<fec-mode xmlns:typex="http://openconfig.net/yang/platform-types">typex:FEC_AUTO</fec-mode>
-					<module-functional-type xmlns:typex="http://openconfig.net/yang/transport-types">typex:TYPE_DIGITAL_COHERENT_OPTIC</module-functional-type>
-					<vendor>Cisco</vendor>
-					<vendor-part>400zr-QSFP-DD</vendor-part>
-					<vendor-rev>01</vendor-rev>
-					<serial-no>1567321</serial-no>
-				</state>
-				<physical-channels>
-					<channel>
-						<index>1</index>
-						<config>
-							<index>1</index>
-							<associated-optical-channel>channel-6</associated-optical-channel>
-						</config>
-						<!--state>
-							<index>1</index>
-							<associated-optical-channel>channel-4</associated-optical-channel>
-						</state-->
-					</channel>
-				</physical-channels>
-			</transceiver>
-		</component>
-    <component>
-                        <name>port-6</name>
-                        <config>
-                                <name>port-6</name>
-                        </config>
-                        <state>
-                                <name>port-6</name>
-                        <type xmlns:typex="http://openconfig.net/yang/platform-types">typex:PORT</type>
-                        </state>
-                        <subcomponents>
-                                <subcomponent>
-                                        <name>channel-6</name>
-                                        <config>
-                                                <name>channel-6</name>
-                                        </config>
-                                        <state>
-                                                <name>channel-6</name>
-                                        </state>
-                                </subcomponent>
-                        </subcomponents>
-                        <properties>
-                                <property>
-                                        <name>onos-index</name>
-                                        <config>
-                                                <name>onos-index</name>
-                                                <value>4</value>
-                                        </config>
-                                        <state>
-                                                <name>onos-index</name>
-                                                <value>4</value>
-                                        </state>
-                                </property>
-                                <property>
-                                        <name>odtn-port-type</name>
-                                        <config>
-                                                <name>odtn-port-type</name>
-                                                <value>line</value>
-                                        </config>
-                                        <state>
-                                                <name>odtn-port-type</name>
-                                                <value>line</value>
-                                        </state>
-                                </property>
-                        </properties>
-                </component>
-
-   
-	</components>
-	<terminal-device xmlns="http://openconfig.net/yang/terminal-device">
-             <logical-channels>
-                  <!--Description: Optical logical link-->
-                  <channel>
-
-			<!--Description: Line (OTN) Port-->
-			<index>4</index>
-			<config>
-				<index>4</index>
-				<description>Logical channel 4</description>
-				<admin-state>DISABLED</admin-state>
-				<logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type>
-				<loopback-mode>NONE</loopback-mode>
-			</config>
-			<state>
-				<index>4</index>
-				<description>Logical channel 4</description>
-				<admin-state>DISABLED</admin-state>
-				<logical-channel-type xmlns:type="http://openconfig.net/yang/transport-types">type:PROT_OTN</logical-channel-type>
-				<loopback-mode>NONE</loopback-mode>
-				<link-state>UP</link-state>
-			</state>
-		   	<ingress>
-				<config>
-					<transceiver>transceiver-6</transceiver>
-				</config>
-				<state>
-					<transceiver>transceiver-6</transceiver>
-				</state>
-			</ingress>
-			<otn>
-				<config>
-					<tti-msg-expected>test1</tti-msg-expected>
-					<tti-msg-transmit>test1</tti-msg-transmit>
-				</config>
-				<state>
-					<tti-msg-expected>test1</tti-msg-expected>
-					<tti-msg-transmit>test1</tti-msg-transmit>
-					<tti-msg-auto>0</tti-msg-auto>
-					<tti-msg-recv>0</tti-msg-recv>
-					<rdi-msg>0</rdi-msg>
-					<errored-seconds>0</errored-seconds>
-					<severely-errored-seconds>0</severely-errored-seconds>
-					<unavailable-seconds>0</unavailable-seconds>
-					<code-violations>0</code-violations>
-					<fec-uncorrectable-words>0</fec-uncorrectable-words>
-					<fec-corrected-bytes>0</fec-corrected-bytes>
-					<fec-corrected-bits>0</fec-corrected-bits>
-					<background-block-errors>0</background-block-errors>
-					<pre-fec-ber>
-						<instant>0.0</instant>
-						<avg>0.0</avg>
-						<min>0.0</min>
-						<max>0.0</max>
-					</pre-fec-ber>
-					<post-fec-ber>
-						<instant>0.0</instant>
-						<avg>0.0</avg>
-						<min>0.0</min>
-						<max>0.0</max>
-					</post-fec-ber>
-					<q-value>
-						<instant>0.0</instant>
-						<avg>0.0</avg>
-						<min>0.0</min>
-						<max>0.0</max>
-						<interval>0</interval>
-					</q-value>
-					<esnr>
-						<instant>0.0</instant>
-						<avg>0.0</avg>
-						<min>0.0</min>
-						<max>0.0</max>
-						<interval>0</interval>
-					</esnr>
-				</state>
-			</otn>
-			<logical-channel-assignments>
-				<assignment>
-					<index>1</index>
-					<config>
-							<index>1</index>
-							<description>Optical channel assigned 100</description>
-							<allocation>100</allocation>
-							<assignment-type>OPTICAL_CHANNEL</assignment-type>
-							<optical-channel>channel-6</optical-channel>
-					</config>
-					<state>
-							<index>1</index>
-							<description>Optical channel assigned 100</description>
-							<allocation>100</allocation>
-							<assignment-type>OPTICAL_CHANNEL</assignment-type>
-							<optical-channel>channel-6</optical-channel>
-					</state>
-				</assignment>
-			</logical-channel-assignments>
-                  </channel>
-           </logical-channels>
-    	   <operational-modes>
-           <mode>
-	   	<mode-id>1</mode-id>
-			<state>
-				<mode-id>1</mode-id>
-				<description>FEC1</description>
-				<vendor-id>Ericsson</vendor-id>
-			</state>
-		</mode>
-		<mode>
-		    <mode-id>2</mode-id>
-			<state>
-				<mode-id>2</mode-id>
-				<description>FEC2</description>
-				<vendor-id>Ericsson</vendor-id>
-			</state>
-		</mode>		
-    	   </operational-modes>
-	</terminal-device>
-</config>
-
diff --git a/src/tests/ofc24/tests/__init__.py b/src/tests/ofc24/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612
--- /dev/null
+++ b/src/tests/ofc24/tests/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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.
+
diff --git a/src/tests/ofc24/tests/test_functional_bootstrap.py b/src/tests/ofc24/tests/test_functional_bootstrap.py
new file mode 100644
index 0000000000000000000000000000000000000000..bc648d16de57c8c287c7d601f994cb81ed45bc04
--- /dev/null
+++ b/src/tests/ofc24/tests/test_functional_bootstrap.py
@@ -0,0 +1,67 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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.
+
+import logging, os, time
+from common.Constants import DEFAULT_CONTEXT_NAME
+from common.proto.context_pb2 import ContextId, DeviceOperationalStatusEnum, Empty
+from common.tools.descriptor.Loader import DescriptorLoader, check_descriptor_load_results, validate_empty_scenario
+from common.tools.object_factory.Context import json_context_id
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from tests.Fixtures import context_client, device_client # pylint: disable=unused-import
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+DESCRIPTOR_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'descriptors_topology.json')
+ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME))
+
+def test_scenario_bootstrap(
+    context_client : ContextClient, # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,   # pylint: disable=redefined-outer-name
+) -> None:
+    validate_empty_scenario(context_client)
+
+    descriptor_loader = DescriptorLoader(
+        descriptors_file=DESCRIPTOR_FILE, context_client=context_client, device_client=device_client)
+    results = descriptor_loader.process()
+    check_descriptor_load_results(results, descriptor_loader)
+    descriptor_loader.validate()
+
+    # Verify the scenario has no services/slices
+    response = context_client.GetContext(ADMIN_CONTEXT_ID)
+    assert len(response.service_ids) == 0
+    assert len(response.slice_ids) == 0
+
+def test_scenario_devices_enabled(
+    context_client : ContextClient,         # pylint: disable=redefined-outer-name
+) -> None:
+    """
+    This test validates that the devices are enabled.
+    """
+    DEVICE_OP_STATUS_ENABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
+
+    num_devices = -1
+    num_devices_enabled, num_retry = 0, 0
+    while (num_devices != num_devices_enabled) and (num_retry < 10):
+        time.sleep(1.0)
+        response = context_client.ListDevices(Empty())
+        num_devices = len(response.devices)
+        num_devices_enabled = 0
+        for device in response.devices:
+            if device.device_operational_status != DEVICE_OP_STATUS_ENABLED: continue
+            num_devices_enabled += 1
+        LOGGER.info('Num Devices enabled: {:d}/{:d}'.format(num_devices_enabled, num_devices))
+        num_retry += 1
+    assert num_devices_enabled == num_devices
diff --git a/src/tests/ofc24/tests/test_functional_cleanup.py b/src/tests/ofc24/tests/test_functional_cleanup.py
new file mode 100644
index 0000000000000000000000000000000000000000..5f1ce23f13051759e0e688a42c7118eaff8d3c72
--- /dev/null
+++ b/src/tests/ofc24/tests/test_functional_cleanup.py
@@ -0,0 +1,44 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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.
+
+import logging, os
+from common.Constants import DEFAULT_CONTEXT_NAME
+from common.proto.context_pb2 import ContextId
+from common.tools.descriptor.Loader import DescriptorLoader, validate_empty_scenario
+from common.tools.object_factory.Context import json_context_id
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from tests.Fixtures import context_client, device_client    # pylint: disable=unused-import
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+DESCRIPTOR_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'descriptors_topology.json')
+ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME))
+
+def test_scenario_cleanup(
+    context_client : ContextClient, # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,   # pylint: disable=redefined-outer-name
+) -> None:
+    # Verify the scenario has no services/slices
+    response = context_client.GetContext(ADMIN_CONTEXT_ID)
+    assert len(response.service_ids) == 0
+    assert len(response.slice_ids) == 0
+
+    # Load descriptors and validate the base scenario
+    descriptor_loader = DescriptorLoader(
+        descriptors_file=DESCRIPTOR_FILE, context_client=context_client, device_client=device_client)
+    descriptor_loader.validate()
+    descriptor_loader.unload()
+    validate_empty_scenario(context_client)
diff --git a/src/tests/ofc24/tests/test_functional_create_service.py b/src/tests/ofc24/tests/test_functional_create_service.py
new file mode 100644
index 0000000000000000000000000000000000000000..74c74483eb82325afec2cae833ebd460566da153
--- /dev/null
+++ b/src/tests/ofc24/tests/test_functional_create_service.py
@@ -0,0 +1,102 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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.
+
+import logging, os, random
+from common.Constants import DEFAULT_CONTEXT_NAME
+from common.proto.context_pb2 import ContextId, Empty, ServiceTypeEnum
+from common.proto.kpi_sample_types_pb2 import KpiSampleType
+from common.tools.descriptor.Loader import DescriptorLoader
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from common.tools.object_factory.Context import json_context_id
+from context.client.ContextClient import ContextClient
+from monitoring.client.MonitoringClient import MonitoringClient
+from tests.Fixtures import context_client, monitoring_client                    # pylint: disable=unused-import
+from tests.tools.mock_osm.MockOSM import MockOSM
+from .Fixtures import osm_wim                                                   # pylint: disable=unused-import
+from .Objects import WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+DESCRIPTOR_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'descriptors_emulated.json')
+ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME))
+
+def test_service_creation(context_client : ContextClient, osm_wim : MockOSM): # pylint: disable=redefined-outer-name
+    # Load descriptors and validate the base scenario
+    descriptor_loader = DescriptorLoader(descriptors_file=DESCRIPTOR_FILE, context_client=context_client)
+    descriptor_loader.validate()
+
+    # Verify the scenario has no services/slices
+    response = context_client.GetContext(ADMIN_CONTEXT_ID)
+    assert len(response.service_ids) == 0
+    assert len(response.slice_ids) == 0
+
+    # Create Connectivity Service
+    service_uuid = osm_wim.create_connectivity_service(WIM_SERVICE_TYPE, WIM_SERVICE_CONNECTION_POINTS)
+    osm_wim.get_connectivity_service_status(service_uuid)
+
+    # Ensure slices and services are created
+    response = context_client.ListSlices(ADMIN_CONTEXT_ID)
+    LOGGER.info('Slices[{:d}] = {:s}'.format(len(response.slices), grpc_message_to_json_string(response)))
+    assert len(response.slices) == 1 # OSM slice
+
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    LOGGER.info('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response)))
+    assert len(response.services) == 2 # 1xL3NM + 1xTAPI
+
+    for service in response.services:
+        service_id = service.service_id
+        response = context_client.ListConnections(service_id)
+        LOGGER.info('  ServiceId[{:s}] => Connections[{:d}] = {:s}'.format(
+            grpc_message_to_json_string(service_id), len(response.connections), grpc_message_to_json_string(response)))
+
+        if service.service_type == ServiceTypeEnum.SERVICETYPE_L3NM:
+            assert len(response.connections) == 1 # 1 connection per service
+        elif service.service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE:
+            assert len(response.connections) == 1 # 1 connection per service
+        else:
+            str_service = grpc_message_to_json_string(service)
+            raise Exception('Unexpected ServiceType: {:s}'.format(str_service))
+
+
+def test_scenario_kpi_values_created(
+    monitoring_client: MonitoringClient,    # pylint: disable=redefined-outer-name
+) -> None:
+    """
+    This test validates that KPI values have been inserted into the monitoring database.
+    We short k KPI descriptors to test.
+    """
+    response = monitoring_client.GetKpiDescriptorList(Empty())
+    kpi_descriptors = random.choices(response.kpi_descriptor_list, k=2)
+
+    for kpi_descriptor in kpi_descriptors:
+        MSG = 'KPI(kpi_uuid={:s}, device_uuid={:s}, endpoint_uuid={:s}, service_uuid={:s}, kpi_sample_type={:s})...'
+        LOGGER.info(MSG.format(
+            str(kpi_descriptor.kpi_id.kpi_id.uuid), str(kpi_descriptor.device_id.device_uuid.uuid),
+            str(kpi_descriptor.endpoint_id.endpoint_uuid.uuid), str(kpi_descriptor.service_id.service_uuid.uuid),
+            str(KpiSampleType.Name(kpi_descriptor.kpi_sample_type))))
+        response = monitoring_client.GetInstantKpi(kpi_descriptor.kpi_id)
+        kpi_uuid = response.kpi_id.kpi_id.uuid
+        assert kpi_uuid == kpi_descriptor.kpi_id.kpi_id.uuid
+        kpi_value_type = response.kpi_value.WhichOneof('value')
+        if kpi_value_type is None:
+            MSG = '  KPI({:s}): No instant value found'
+            LOGGER.warning(MSG.format(str(kpi_uuid)))
+        else:
+            kpi_timestamp = response.timestamp.timestamp
+            assert kpi_timestamp > 0
+            assert kpi_value_type == 'floatVal'
+            kpi_value = getattr(response.kpi_value, kpi_value_type)
+            MSG = '  KPI({:s}): timestamp={:s} value_type={:s} value={:s}'
+            LOGGER.info(MSG.format(str(kpi_uuid), str(kpi_timestamp), str(kpi_value_type), str(kpi_value)))
diff --git a/src/tests/ofc24/tests/test_functional_delete_service.py b/src/tests/ofc24/tests/test_functional_delete_service.py
new file mode 100644
index 0000000000000000000000000000000000000000..daff29064f07e8117a4503fc243c7acac9f88bc6
--- /dev/null
+++ b/src/tests/ofc24/tests/test_functional_delete_service.py
@@ -0,0 +1,74 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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.
+
+import logging, os
+from common.Constants import DEFAULT_CONTEXT_NAME
+from common.proto.context_pb2 import ContextId, ServiceTypeEnum
+from common.tools.descriptor.Loader import DescriptorLoader
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from common.tools.object_factory.Context import json_context_id
+from context.client.ContextClient import ContextClient
+from tests.Fixtures import context_client   # pylint: disable=unused-import
+from tests.tools.mock_osm.MockOSM import MockOSM
+from .Fixtures import osm_wim               # pylint: disable=unused-import
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+DESCRIPTOR_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'descriptors_emulated.json')
+ADMIN_CONTEXT_ID = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME))
+
+def test_service_removal(context_client : ContextClient, osm_wim : MockOSM): # pylint: disable=redefined-outer-name
+    # Ensure slices and services are created
+    response = context_client.ListSlices(ADMIN_CONTEXT_ID)
+    LOGGER.info('Slices[{:d}] = {:s}'.format(len(response.slices), grpc_message_to_json_string(response)))
+    assert len(response.slices) == 1 # OSM slice
+
+    response = context_client.ListServices(ADMIN_CONTEXT_ID)
+    LOGGER.info('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response)))
+    assert len(response.services) == 2 # 1xL3NM + 1xTAPI
+
+    service_uuids = set()
+    for service in response.services:
+        service_id = service.service_id
+        response = context_client.ListConnections(service_id)
+        LOGGER.info('  ServiceId[{:s}] => Connections[{:d}] = {:s}'.format(
+            grpc_message_to_json_string(service_id), len(response.connections), grpc_message_to_json_string(response)))
+
+        if service.service_type == ServiceTypeEnum.SERVICETYPE_L3NM:
+            assert len(response.connections) == 1 # 1 connection per service
+            service_uuid = service_id.service_uuid.uuid
+            service_uuids.add(service_uuid)
+            osm_wim.conn_info[service_uuid] = {}
+        elif service.service_type == ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE:
+            assert len(response.connections) == 1 # 1 connection per service
+        else:
+            str_service = grpc_message_to_json_string(service)
+            raise Exception('Unexpected ServiceType: {:s}'.format(str_service))
+
+    # Identify service to delete
+    assert len(service_uuids) == 1  # assume a single L3NM service has been created
+    service_uuid = set(service_uuids).pop()
+
+    # Delete Connectivity Service
+    osm_wim.delete_connectivity_service(service_uuid)
+
+    # Verify the scenario has no services/slices
+    response = context_client.GetContext(ADMIN_CONTEXT_ID)
+    assert len(response.service_ids) == 0
+    assert len(response.slice_ids) == 0
+
+    # Load descriptors and validate the base scenario
+    descriptor_loader = DescriptorLoader(descriptors_file=DESCRIPTOR_FILE, context_client=context_client)
+    descriptor_loader.validate()