From: Sangeetha mani Date: Wed, 21 Oct 2020 08:55:35 +0000 (-0700) Subject: Issue-ID: RIC-149 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=029cc1f45c4c40e0867104b730495d4d2fe468b8;p=it%2Ftest.git Issue-ID: RIC-149 As per reviewer comments Dockerfile of nanobot : Moved 57 to 78 lines to up(starting point) Issue-ID: RIC-149 1) Fixed Dockerfile for Jenkins job. 2) values.yaml: Revert the ORAN repo image. 3) Dockerfile: Added SDLWrapper.py and RICSDL packages,fixed Nccclient issue, RMR packages and kubectl installed. Issue-ID: RIC-149 1) global_properties.robot: Added global variables for RAN elements and XAPP. 2) values.yaml: Added E2sim name and namespace. 3) job-ric-robot-run.yaml: Added rbac service to e2sim pod and logs access. 4) Copied negative_appmgr_tests.robot, ric_utils.robot, dashboard_interface.robot files inside configmap-src path. 5) e2e.robot: Added packet captures related test cases between e2sim and xapp Issue-ID: RIC-149 As per the review comments by Dave, updated the following changes. 1) Removed lib directory inside configmap-src/public 2) Removed SDLWrapper.py and shell scripts 3) Updated configmaps-robot.yaml and job-ric-robot-run.yaml due to this change 4) Planning to update the packages to install SDLWrapper.py via docker images 5) Removed shell script related code in e2term_interface.robot 6) Removed shell script related code in health-check.robot Issue-ID: RIC-149 values.yaml: Added submgr related parameters Signed-off-by: Sangeetha mani Change-Id: Ic034cfe153ba6ae9af7add095c330f7146ab6458 --- diff --git a/ric_robot_suite/docker/nanobot/Dockerfile b/ric_robot_suite/docker/nanobot/Dockerfile index dbafdb0..46a86be 100644 --- a/ric_robot_suite/docker/nanobot/Dockerfile +++ b/ric_robot_suite/docker/nanobot/Dockerfile @@ -1,82 +1,109 @@ -# Copyright (c) 2019 AT&T Intellectual Property. -# -# 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-alpine AS nanobot-build - -RUN apk update && apk add git build-base libffi-dev libxml2 libxslt libxml2-dev libxslt-dev openssl-dev - -RUN pip install UUID -RUN pip install kubernetes -RUN pip install redis -RUN pip install asyncio -RUN pip install websockets -RUN pip install robotframework -RUN pip install robotframework-requests -RUN pip install robotframework-ncclient - -WORKDIR /tmp/ -RUN git clone -b 3.0.1-ONAP https://gerrit.onap.org/r/testsuite/python-testing-utils.git - -FROM python:3-alpine -MAINTAINER "RIC" -LABEL name="Docker image for the RIC Robot Testing Framework" - -ENV ROBOT_HOME="/robot" -ENV ROBOT_OPTIONS="-T -d /robot/log --console verbose -C off -P /robot/lib/python" -ENV KUBECONFIG="/robot/etc/kubernetes-admin-conf" -ENV PYTHONPATH="/robot/lib/python" -ENV RICPLT_NAMESPACE=ricplt -ENV RICPLT_RELEASE_NAME=ric-full -ENV RICPLT_COMPONENTS="a1mediator appmgr dbaas e2mgr e2term rtmgr" - -RUN apk update && apk add libxslt -COPY --from=nanobot-build /usr/local/lib/python3.8 /usr/local/lib/python3.8 -COPY --from=nanobot-build /usr/local/bin/robot /usr/local/bin - -RUN mkdir -p /robot/lib/python - -# ONAP eteutils -# we only need a few things from this so we won't install the whole thing. -COPY --from=nanobot-build /tmp/python-testing-utils/eteutils/StringTemplater.py /robot/lib/python -COPY --from=nanobot-build /tmp/python-testing-utils/eteutils/UUID.py /robot/lib/python -COPY ric-python-utils/ricutils/*.py /robot/lib/python/ - -# -# for the nanobot container, we only need a subset of the various support -# files/libraries, so we pick and choose what to copy.. -RUN mkdir /robot/resources -COPY robot/resources/json_templater.robot /robot/resources -COPY robot/resources/a1mediator /robot/resources/a1mediator -COPY robot/resources/appmgr /robot/resources/appmgr -COPY robot/resources/dashboard /robot/resources/dashboard -COPY robot/resources/e2mgr /robot/resources/e2mgr -COPY robot/resources/e2sim /robot/resources/e2sim -COPY robot/resources/e2term /robot/resources/e2term -COPY robot/resources/o1mediator /robot/resources/o1mediator -COPY robot/resources/ric /robot/resources/ric -COPY robot/resources/rnib /robot/resources/rnib -COPY robot/resources/rtmgr /robot/resources/rtmgr -COPY robot/resources/xapps /robot/resources/xapps -# this will actually be overlaid by the helm chart, but -# it's good to have the placeholder. -COPY robot/resources/global_properties.robot /robot/resources - -RUN mkdir -p /robot/assets/templates -COPY robot/assets/templates/e2mgr_setup_nodeb.template /robot/assets/templates - -RUN python -m compileall /robot/lib/python - -WORKDIR / - -CMD ["sleep", "9125d"] + # Copyright (c) 2019 AT&T Intellectual Property. + # Copyright (c) 2020 HCL Technologies. + # 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.8-alpine AS nanobot-build + + RUN apk update && apk add git build-base libffi-dev libxml2 libxslt libxml2-dev libxslt-dev openssl-dev + RUN apk update && apk add git gcc linux-headers libc-dev cmake pkgconfig make + + + RUN pip install kubernetes + RUN pip install redis + RUN pip install asyncio + RUN pip install websockets + RUN pip install robotframework + RUN pip install robotframework-requests + RUN pip install robotframework-ncclient + RUN pip install UUID + WORKDIR /tmp/ + RUN git clone -b 3.0.1-ONAP https://gerrit.onap.org/r/testsuite/python-testing-utils.git + + + #rmr probe for e2term + RUN pip install msgpack + RUN python3 -m pip install ricsdl + RUN apk add curl + RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.19.2/bin/linux/amd64/kubectl + RUN chmod +x ./kubectl + RUN mv ./kubectl /usr/local/bin/kubectl + + + RUN apk add cmake git gcc + WORKDIR / + RUN git clone https://gerrit.o-ran-sc.org/r/ric-plt/lib/rmr && \ + cd rmr && \ + mkdir build && \ + cd build && \ + cmake -DPACK_EXTERNALS=1 -DDEV_PKG=1 .. && \ + make install + RUN mkdir -p /opt/e2 + RUN cp /rmr/build/src/support/rmr_probe /opt/e2/ + + + + FROM python:3.8-alpine + MAINTAINER "RIC" + LABEL name="Docker image for the RIC Robot Testing Framework" + + ENV ROBOT_HOME="/robot" + ENV ROBOT_OPTIONS="-T -d /robot/log --console verbose -C off -P /robot/lib/python" + ENV KUBECONFIG="/robot/etc/kubernetes-admin-conf" + ENV PYTHONPATH="/robot/lib/python" + ENV RICPLT_NAMESPACE=ricplt + ENV RICPLT_RELEASE_NAME=ric-full + ENV RICPLT_COMPONENTS="a1mediator appmgr dbaas e2mgr e2term rtmgr" + ENV DBAAS_SERVICE_HOST=service-ricplt-dbaas-tcp.ricplt.svc.cluster.local + ENV DBAAS_SERVICE_PORT=6379 + RUN apk update && apk add libxslt + COPY --from=nanobot-build /usr/local/lib/python3.8 /usr/local/lib/python3.8 + COPY --from=nanobot-build /usr/local/bin/robot /usr/local/bin + + RUN apk add wget + RUN mkdir -p /robot/lib/python + WORKDIR ric-python-utils/ricutils + RUN wget -o SDLWrapper.py "https://gerrit.o-ran-sc.org/r/gitweb?p=ric-plt/xapp-frame-py.git;a=blob_plain;f=ricxappframe/xapp_sdl.py" + # ONAP eteutils + # we only need a few things from this so we won't install the whole thing. + COPY --from=nanobot-build /tmp/python-testing-utils/eteutils/StringTemplater.py /robot/lib/python + COPY --from=nanobot-build /tmp/python-testing-utils/eteutils/UUID.py /robot/lib/python + COPY ric-python-utils/ricutils/*.py /robot/lib/python/ + + # + # for the nanobot container, we only need a subset of the various support + # files/libraries, so we pick and choose what to copy.. + RUN mkdir /robot/resources + COPY robot/resources/json_templater.robot /robot/resources + COPY robot/resources/a1mediator /robot/resources/a1mediator + COPY robot/resources/appmgr /robot/resources/appmgr + COPY robot/resources/dashboard /robot/resources/dashboard + COPY robot/resources/e2mgr /robot/resources/e2mgr + COPY robot/resources/e2sim /robot/resources/e2sim + COPY robot/resources/e2term /robot/resources/e2term + COPY robot/resources/o1mediator /robot/resources/o1mediator + COPY robot/resources/ric /robot/resources/ric + COPY robot/resources/rnib /robot/resources/rnib + COPY robot/resources/rtmgr /robot/resources/rtmgr + COPY robot/resources/xapps /robot/resources/xapps + # this will actually be overlaid by the helm chart, but + # it's good to have the placeholder. + COPY robot/resources/global_properties.robot /robot/resources + + RUN mkdir -p /robot/assets/templates + COPY robot/assets/templates/e2mgr_setup_nodeb.template /robot/assets/templates + + RUN python -m compileall /robot/lib/python + + WORKDIR / + CMD ["sleep", "9125d"] + diff --git a/ric_robot_suite/helm/nanobot/configmap-src/public/properties/global_properties.robot b/ric_robot_suite/helm/nanobot/configmap-src/public/properties/global_properties.robot index e8c95d0..0e9d3ff 100644 --- a/ric_robot_suite/helm/nanobot/configmap-src/public/properties/global_properties.robot +++ b/ric_robot_suite/helm/nanobot/configmap-src/public/properties/global_properties.robot @@ -1,5 +1,5 @@ # Copyright (c) 2019 AT&T Intellectual Property. -# +# Copyright (c) 2020 HCL Technologies Limited. # 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 @@ -19,6 +19,7 @@ {{- $release := default "r1" .Values.ric.robot.release }} {{- $testxapp := default "robot-xapp" .Values.ric.robot.environment.xapp }} {{- $dt := "deployment" }} +{{- $e2_suff := "alpha" }} {{- $ds := "" }} # *** Settings *** @@ -28,6 +29,8 @@ Documentation store all properties that can change or are used in multipl *** Variables *** +#{{ printf "%s.%s" (include "common.servicename.a1mediator.http" .) $ricplt }} +# {{ printf "%s-alpha.%s" (include "common.servicename.e2term.rmr" .) $ricplt}} &{GLOBAL_RICPLT_COMPONENTS} {{- range $k, $v := .Values.ric.platform.components }} {{- if $v }} {{- $ct := index $v "controller" }} @@ -70,14 +73,21 @@ ${GLOBAL_INJECTED_E2MGR_USER} {{ .Values.ric.platform.components.e2mgr.u ${GLOBAL_INJECTED_E2MGR_PASSWORD} {{ .Values.ric.platform.components.e2mgr.password }} {{- end }} # +{{- if .Values.ric.platform.components.e2term }} +${GLOBAL_INJECTED_E2TERM_IP_ADDR} {{ printf "%s-alpha.%s" (include "common.servicename.e2term.rmr" .) $ricplt}} +${GLOBAL_E2TERM_SERVER_PORT} {{ include "common.serviceport.e2term.rmr.data" . }} +{{- end }} +# {{- if .Values.ric.platform.components.rtmgr }} ${GLOBAL_RTMGR_SERVER_PROTOCOL} {{ default "http" .Values.ric.platform.components.rtmgr.protocol }} ${GLOBAL_INJECTED_RTMGR_IP_ADDR} {{ printf "%s.%s" (include "common.servicename.rtmgr.http" .) $ricplt }} -${GLOBAL_RTMGR_SERVER_PORT} {{ include "common.serviceport.e2mgr.http" . }} +${GLOBAL_RTMGR_SERVER_PORT} {{ include "common.serviceport.rtmgr.http" . }} +${GLOBAL_RTMGR_SERVER_HTTP_PORT} {{ default "8080" }} ${GLOBAL_INJECTED_RTMGR_USER} {{ .Values.ric.platform.components.rtmgr.user }} ${GLOBAL_INJECTED_RTMGR_PASSWORD} {{ .Values.ric.platform.components.rtmgr.password }} {{- end }} # +# {{- if .Values.ric.platform.components.a1mediator }} ${GLOBAL_A1MEDIATOR_SERVER_PROTOCOL} {{ default "http" .Values.ric.platform.components.a1mediator.protocol }} ${GLOBAL_INJECTED_A1MEDIATOR_IP_ADDR} {{ printf "%s.%s" (include "common.servicename.a1mediator.http" .) $ricplt }} @@ -87,6 +97,9 @@ ${GLOBAL_A1MEDIATOR_TARGET_XAPP} {{ default $testxapp .Values.ric.plat {{- end }} # {{- if .Values.ric.platform.components.o1mediator }} +${GLOBAL_O1MEDIATOR_SERVER_PROTOCOL} {{ default "http" .Values.ric.platform.components.o1mediator.protocol }} +${GLOBAL_O1MEDIATOR_HTTP_SERVER} {{ printf "%s.%s" (include "common.servicename.o1mediator.http" .) $ricplt }} +${GLOBAL_O1MEDIATOR_SERVER_PORT} {{ include "common.serviceport.o1mediator.http" . }} ${GLOBAL_O1MEDIATOR_HOST} {{ printf "%s.%s" (include "common.servicename.o1mediator.tcp.netconf" .) $ricplt }} ${GLOBAL_O1MEDIATOR_PORT} {{ include "common.serviceport.o1mediator.tcp.netconf" . }} ${GLOBAL_O1MEDIATOR_USER} {{ .Values.ric.platform.components.o1mediator.user }} @@ -96,8 +109,18 @@ ${GLOBAL_O1MEDIATOR_XAPP_VERSION} {{ default "1.0" .Values.ric.platform.co ${GLOBAL_O1MEDIATOR_DEPLOYMENT_WAIT} {{ default "180" .Values.ric.platform.components.o1mediator.xapp.wait }} {{- end }} # +{{- if .Values.ric.platform.components.submgr }} +${GLOBAL_SUBMGR_SERVER_PROTOCOL} {{ default "http" .Values.ric.platform.components.submgr.protocol }} +${GLOBAL_SUBMGR_HTTP_SERVER} {{ printf "%s.%s" (include "common.servicename.submgr.http" .) $ricplt }} +${GLOBAL_SUBMGR_SERVER_PORT} {{ include "common.serviceport.submgr.http" . }} +${GLOBAL_SUBMGR_SERVER_PROTOCOL} {{ default "http" .Values.ric.platform.components.submgr.protocol }} +${GLOBAL_INJECTED_SUBMGR_IP_ADDR} {{ printf "%s.%s" (include "common.servicename.submgr.http" .) $ricplt }} +${GLOBAL_INJECTED_SUBMGR_USER} {{ .Values.ric.platform.components.submgr.user }} +${GLOBAL_INJECTED_SUBMGR_PASSWORD} {{ .Values.ric.platform.components.submgr.password }} +{{- end }} # ${GLOBAL_TEST_XAPP} {{ default "xapp-std" .Values.ric.robot.environment.xapp }} +${GLOBAL_TEST_XAPP_ONBOARDER} {{ default "deployment|deployment-ricplt-xapp-onboarder" }} # ${GLOBAL_TEST_NODEB_NAME} {{ default "AAAA456789" .Values.ric.robot.environment.gNodeB.name }} ${GLOBAL_TEST_NODEB_ADDRESS} {{ default "10.0.0.3" .Values.ric.robot.environment.gNodeB.address }} @@ -106,3 +129,8 @@ ${GLOBAL_TEST_NODEB_PORT} {{ default "36421" .Values.ric.robot. ${GLOBAL_DASH_SERVER_PROTOCOL} {{ default "http" .Values.ric.robot.environment.dashboard.protocol }} ${GLOBAL_DASH_SERVER_PORT} {{ default "31080" .Values.ric.robot.environment.dashboard.port }} ${GLOBAL_INJECTED_DASH_IP_ADDR} {{ default "127.0.0.1" .Values.ric.robot.environment.dashboard.port }} +${GLOBAL_XAPP} {{ .Values.ric.robot.environment.xapp }} +${Global_RAN_NAMESPACE} {{ .Values.ric.robot.environment.gNodeB.ran_namespace }} +${Global_RAN_DEPLOYMENT} {{ .Values.ric.robot.environment.gNodeB.ran_deployment }} + + diff --git a/ric_robot_suite/helm/nanobot/configmap-src/public/resources/a1mediator_interface.robot b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/a1mediator_interface.robot new file mode 100644 index 0000000..fa0efff --- /dev/null +++ b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/a1mediator_interface.robot @@ -0,0 +1,128 @@ +*** Settings *** +Documentation Keywords for interacting with the A1 interface, including policy creation, instantiaton, and deletion + +Library RequestsLibrary + +Resource /robot/resources/global_properties.robot + +Resource /robot/resources/ric/ric_utils.robot + +*** Variables *** +${A1MEDIATOR_BASE_PATH} /a1-p/policytypes +${A1MEDIATOR_ENDPOINT} ${GLOBAL_A1MEDIATOR_SERVER_PROTOCOL}://${GLOBAL_INJECTED_A1MEDIATOR_IP_ADDR}:${GLOBAL_A1MEDIATOR_SERVER_PORT} + +*** Keywords *** + +Run A1Mediator Health Check + [Documentation] Runs A1Mediator Health check + Log To Console Entering a1mediator + ${resp} = Run A1mediator GET Request + Log To Console ${resp} + +Create A1 Policy Type + [Documentation] Create a new policy via the A1 Mediator. + [Arguments] ${type} ${name} ${description} ${properties} ${required}=@{EMPTY} + ${typeID} = Convert To Integer ${type} + Should Be True ${type} > 0 Policy type must be an integer > 0 + ${createSchema} = Create Dictionary + ... $schema=http://json-schema.org/draft-07/schema# + ... type=object + ... properties=${properties} + ... required=@{required} + ${createBody} = Create Dictionary + ... name=${name} + ... policy_type_id=${typeID} + ... description=${description} + ... create_schema=${createSchema} + ${createJSON} = Evaluate json.dumps(&{createBody}) json,uuid + ${resp} = Run A1Mediator PUT Request /${type} body=${createJSON} + [Return] ${resp} + +Instantiate A1 Policy + [Documentation] Create a new instance of an A1 policy + [Arguments] ${type} ${instance} ${properties}=${EMPTY} + ${typeID} = Convert To Integer ${type} + Should Be True ${type} > 0 Policy type must be an integer > 0 + ${instanceJSON} = Evaluate json.dumps(&{properties}) json,uuid + ${resp} = Run A1Mediator PUT Request /${type}/policies/${instance} body=${instanceJSON} + [Return] ${resp} + +Delete A1 Instance + [Documentation] Remove an A1 policy instance + [Arguments] ${type} ${instance} + ${typeID} = Convert To Integer ${type} + Should Be True ${type} > 0 Policy type must be an integer > 0 + ${resp} = Run A1Mediator DELETE Request /${type}/policies/${instance} + [Return] ${resp} + +Delete A1 Policy + [Documentation] Remove an A1 policy type + [Arguments] ${type} + ${typeID} = Convert To Integer ${type} + Should Be True ${type} > 0 Policy type must be an integer > 0 + ${resp} = Run A1Mediator DELETE Request /${type} + [Return] ${resp} + +Retrieve A1 Policy + [Documentation] Get a defined policy from A1 + [Arguments] ${type} + ${typeID} = Convert To Integer ${type} + Should Be True ${type} > 0 Policy type must be an integer > 0 + ${resp} = Run A1Mediator GET Request /${type} + [Return] ${resp} + +Retrieve A1 Instance + [Documentation] Get a defined policy from A1. If no instance is specified, retrieve all instances. + [Arguments] ${type} ${instance}=${EMPTY} + ${typeID} = Convert To Integer ${type} + Should Be True ${type} > 0 Policy type must be an integer > 0 + ${resp} = Run Keyword If "${instance}" != "${EMPTY}" + ... Run A1Mediator GET Request /${type}/policies/${instance} + ... ELSE + ... Run A1Mediator GET Request /${type}/policies + [Return] ${resp} + +Retrieve A1 Instance Status + [Documentation] Get policy instance status + [Arguments] ${type} ${instance}=${EMPTY} + ${typeID} = Convert To Integer ${type} + Should Be True ${type} > 0 Policy type must be an integer > 0 + ${resp} = Run A1Mediator GET Request /${type}/policies/${instance}/status + [Return] ${resp} + +Run A1mediator GET Request + [Documentation] Make an HTTP GET request against the XApp manager + [Arguments] ${path}=${EMPTY} + ${session} = Create Session roboA1mediatorGet ${A1MEDIATOR_ENDPOINT} + ${headers} = Create Dictionary Accept=application/json Content-Type=application/json + ${resp} = Get Request roboA1mediatorGet ${A1MEDIATOR_BASE_PATH}${path} headers=${headers} + [Return] ${resp} + +Run A1mediator PUT Request + [Documentation] Make an HTTP PUT request against the XApp manager + [Arguments] ${path}=${EMPTY} ${body}=${EMPTY} + ${session} = Create Session roboA1mediatorPut ${A1MEDIATOR_ENDPOINT} + ${headers} = Create Dictionary Accept=application/json Content-Type=application/json + ${resp} = PUT Request roboA1mediatorPut ${A1MEDIATOR_BASE_PATH}${path} + ... headers=${headers} + ... data=${body} + [Return] ${resp} + +Run A1mediator POST Request + [Documentation] Make an HTTP POST request against the XApp manager + [Arguments] ${path}=${EMPTY} ${body}=${EMPTY} + ${session} = Create Session roboA1mediatorPost ${A1MEDIATOR_ENDPOINT} + ${headers} = Create Dictionary Accept=application/json Content-Type=application/json + ${resp} = POST Request roboA1mediatorPost ${A1MEDIATOR_BASE_PATH}${path} + ... headers=${headers} + ... data=${body} + [Return] ${resp} + +Run A1mediator DELETE Request + [Documentation] Make an HTTP DELETE request against the XApp manager + [Arguments] ${path} + ${session} = Create Session roboA1mediatorDelete ${A1MEDIATOR_ENDPOINT} + ${headers} = Create Dictionary Accept=application/json Content-Type=application/json + ${resp} = Delete Request roboA1mediatorDelete ${A1MEDIATOR_BASE_PATH}${path} headers=${headers} + [Return] ${resp} + diff --git a/ric_robot_suite/helm/nanobot/configmap-src/public/resources/appmgr_interface.robot b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/appmgr_interface.robot new file mode 100644 index 0000000..8b3933e --- /dev/null +++ b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/appmgr_interface.robot @@ -0,0 +1,132 @@ +# Copyright (c) 2019 AT&T Intellectual Property. +# Copyright (c) 2020 HCL Technologies Limited. +# 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. + +**settings *** +Documentation Keywords for interacting with the XApp Manager, including listing, deploying, and undeploying XApps + +Library RequestsLibrary +Library Process +Library Collections +Library OperatingSystem + +Resource /robot/resources/global_properties.robot +Resource /robot/resources/ric/ric_utils.robot + +*** Variables *** +${APPMGR_BASE_PATH} /ric/v1/xapps +${APPMGR_ENDPOINT} ${GLOBAL_APPMGR_SERVER_PROTOCOL}://${GLOBAL_INJECTED_APPMGR_IP_ADDR}:${GLOBAL_APPMGR_SERVER_PORT} + +*** Keywords *** +Run AppMgr Health Check + [Documentation] Runs AppMgr Health check + ${resp}= Run Keyword Get Deployed XApps + +Get Deployed XApps + [Documentation] Obtain the list of deployed XApps from the Appmgr + ${resp} = Run AppMgr GET Request + [Return] ${resp.json()} + +Get Deployable XApps + [Documentation] Obtain the list of deployed XApps from the Appmgr + #${resp} = Run AppMgr GET Request /search/ + ${resp} = Run AppMgr GET Request + Should Be True ${resp} + [Return] ${resp.json()} + +Get XApp By Name + [Documentation] Get installed XApp from Appmgr given name + [Arguments] ${xapp_name} + ${resp} = Run AppMgr GET Request /${xapp_name} + Should Be True ${resp} + [Return] ${resp.json()} + +Get XApp By Name and ID + [Documentation] Get installed XApp from Appmgr by name and ID + [Arguments] ${xapp_name} ${xapp_id} + ${resp}= Run AppMgr GET Request /${xapp_name}/${xapp_id}/ + Should Be True ${resp} + [Return] ${resp.json()} + +Deploy XApp + [Documentation] Create Xapp + [Arguments] ${xapp_name} + &{dict} = Create Dictionary xappName=${xapp_name} + ${data} = Evaluate json.dumps(&{dict}) json + Log To Console ${dict} + Log To Console ${data} + ${resp} = Run AppMgr POST Request ${EMPTY} ${data} + Should Be True ${resp} + [Return] ${resp} + +Deploy XApps + [Documentation] Create one or more XApps + [Arguments] @{xapp_names} + FOR ${xapp} IN @{xapp_names} + Deploy XApp ${xapp} + END + +Undeploy XApp + [Documentation] Remove a deployed XApp + [Arguments] ${xapp_name} + ${resp} = Run AppMgr DELETE Request /${xapp_name} + Should Be True ${resp} + [Return] ${resp} + +Undeploy XApps + [Documentation] Remove one or more deployed XApps + [Arguments] @{xapp_names} + FOR ${xapp} IN @{xapp_names} + Undeploy XApp ${xapp} + +Deploy All Available XApps + [Documentation] Attempt to deploy any not-currently-deployed XApp + @{d} = Get Deployed XApps + @{deployed} = Pluck name ${d} + @{available} = Get Deployable XApps + @{toDeploy} = Subtract From List ${available} ${deployed} + Deploy XApps @{toDeploy} + +Undeploy All Running XApps + [Documentation] Undeploy any deployed XApps + @{d} = Get Deployed XApps + @{deployed} = Pluck name ${d} + Run Keyword If ${deployed} Undeploy XApps @{deployed} + +Run AppMgr GET Request + [Documentation] Make an HTTP GET request against the XApp manager + [Arguments] ${path}=${EMPTY} + ${session} = Create Session roboAppmgrGet ${APPMGR_ENDPOINT} + ${headers} = Create Dictionary Accept=application/json Content-Type=application/json + ${resp} = Get Request roboAppmgrGet ${APPMGR_BASE_PATH}${path} headers=${headers} + [Return] ${resp} + +Run AppMgr POST Request + [Documentation] Make an HTTP POST request against the XApp manager + [Arguments] ${path}=${EMPTY} ${body}=${EMPTY} + ${session} = Create Session roboAppmgrPost ${APPMGR_ENDPOINT} + ${headers} = Create Dictionary Accept=application/json Content-Type=application/json + Log To Console ${headers}.... + Log To Console ${body}.... + ${resp} = Post Request roboAppmgrPost ${APPMGR_BASE_PATH}${path} headers=${headers} data=${body} + [Return] ${resp} + +Run AppMgr DELETE Request + [Documentation] Make an HTTP DELETE request against the XApp manager + [Arguments] ${path} + ${session} = Create Session roboAppmgrDelete ${APPMGR_ENDPOINT} + ${headers} = Create Dictionary Accept=application/json Content-Type=application/json + ${resp} = Delete Request roboAppmgrDelete ${APPMGR_BASE_PATH}${path} headers=${headers} + [Return] ${resp} + + diff --git a/ric_robot_suite/helm/nanobot/configmap-src/public/resources/dashboard_interface.robot b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/dashboard_interface.robot new file mode 100644 index 0000000..3164700 --- /dev/null +++ b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/dashboard_interface.robot @@ -0,0 +1,102 @@ +*** Settings *** +Documentation The main interface for interacting with RIC E2 Manager (Dashboard) . It handles low level stuff like managing the http request library and E2Mgr required fields +Library RequestsLibrary +Library UUID + +Resource /robot/resources/global_properties.robot +Resource /robot/resources/json_templater.robot + +*** Variables *** +${DASH_E2MGR_BASE_PATH} /e2mgr/v1/nodeb #/nodeb /nodeb/setup +${DASH_E2MGR_BASE_VERSION} /e2mgr/v1 +${DASH_ENDPOINT} ${GLOBAL_DASH_SERVER_PROTOCOL}://${GLOBAL_INJECTED_DASH_IP_ADDR}:${GLOBAL_DASH_SERVER_PORT} +${E2MGR_SETUP_NODEB_TEMPLATE} robot/assets/templates/e2mgr_setup_nodeb.template + + +*** Keywords *** +Run Dashboard Health Check + [Documentation] Runs Dashboard Health check + # need to confirm Dashboard Health Check URL + ${data_path}= Set Variable /v1/health + ${resp}= Run Keyword Run Dashboard Get Request ${data_path} + +Dashboard Check NodeB Status + [Documentation] Check NodeB Status + [Arguments] ${ran_name} + ${resp}= Run Keyword Run Dashboard Get NodeB Request ${ran_name} + Should Be Equal As Strings ${resp.json()['connectionStatus']} CONNECTED + +Run Dashboard Get NodeB Request + [Documentation] Runs Dashboard Get NodeB Request + [Arguments] ${ran_name} + ${data_path}= Set Variable ${DASH_E2MGR_BASE_PATH}/${ran_name} + ${resp}= Run Keyword Run Dashboard Get Request ${data_path} + Should Be Equal As Strings ${resp.status_code} 200 + [Return] ${resp} + +Run Dashboard Get All NodeBs Request + [Documentation] Runs Dashboard Get All NodeBs Request + ${data_path}= Set Variable ${DASH_E2MGR_BASE_VERSION}/nodeb-ids + ${resp}= Run Keyword Run Dashboard Get Request ${data_path} + +Run Dashboard Setup NodeB X2 + [documentation] Setup X2 NodeB via E2 Manager + [Arguments] ${ran_name} ${ran_ip} ${ran_port} + ${data_path}= Set Variable ${DASH_E2MGR_BASE_PATH}/x2-setup + ${dict}= Create Dictionary ran_name=${ran_name} ran_ip=${ran_ip} ran_port=${ran_port} + ${data}= Fill JSON Template File ${E2MGR_SETUP_NODEB_TEMPLATE} ${dict} + ${auth}= Create List ${GLOBAL_INJECTED_DASH_USER} ${GLOBAL_INJECTED_DASH_PASSWORD} + ${session}= Create Session e2mgr ${DASH_ENDPOINT} auth=${auth} + ${headers}= Create Dictionary Accept=application/json Content-Type=application/json + ${resp}= Post Request e2mgr ${data_path} data=${data} headers=${headers} + Log Received response from Dashboard ${resp.text} + Should Be Equal As Strings ${resp.status_code} 200 + [Return] ${resp} + +Run Dashboard Setup NodeB Endc + [documentation] Setup Endc NodeB via E2 Manager + [Arguments] ${ran_name} ${ran_ip} ${ran_port} + ${data_path}= Set Variable ${DASH_E2MGR_BASE_PATH}/endc-setup + ${dict}= Create Dictionary ran_name=${ran_name} ran_ip=${ran_ip} ran_port=${ran_port} + ${data}= Fill JSON Template File ${E2MGR_SETUP_NODEB_TEMPLATE} ${dict} + ${auth}= Create List ${GLOBAL_INJECTED_DASH_USER} ${GLOBAL_INJECTED_DASH_PASSWORD} + ${session}= Create Session e2mgr ${DASH_ENDPOINT} auth=${auth} + ${headers}= Create Dictionary Accept=application/json Content-Type=application/json + ${resp}= Post Request e2mgr ${data_path} data=${data} headers=${headers} + Log Received response from Dashboard ${resp.text} + Should Be Equal As Strings ${resp.status_code} 200 + [Return] ${resp} + +Run Dashboard Delete NodeB + [documentation] Delete NodeB via E2 Manager + [Arguments] ${ran_name} + ${data_path}= Set Variable ${DASH_E2MGR_BASE_PATH}/${ran_name} + ${resp}= Run Dashboard Delete Request ${data_path} + Should Be Equal As Strings ${resp.status_code} 200 + + +Run Dashboard Get Request + [Documentation] Runs Dashboard Get Request + [Arguments] ${data_path} + ${auth}= Create List ${GLOBAL_INJECTED_DASH_USER} ${GLOBAL_INJECTED_DASH_PASSWORD} + ${session}= Create Session e2mgr ${DASH_ENDPOINT} auth=${auth} + ${uuid}= Generate UUID + ${headers}= Create Dictionary Accept=application/json Content-Type=application/json + ${resp}= Get Request e2mgr ${data_path} headers=${headers} + Log Received response from Dashboard ${resp.text} + Should Be Equal As Strings ${resp.status_code} 200 + [Return] ${resp} + +Run Dashboard Delete Request + [Documentation] Runs Dashboard Delete Request + [Arguments] ${data_path} + ${auth}= Create List ${GLOBAL_INJECTED_DASH_USER} ${GLOBAL_INJECTED_DASH_PASSWORD} + ${session}= Create Session e2mgr ${DASH_ENDPOINT} auth=${auth} + ${uuid}= Generate UUID + ${headers}= Create Dictionary Accept=application/json Content-Type=application/json + ${resp}= Delete Request e2mgr ${data_path} headers=${headers} + Log Received response from Dashboard ${resp.text} + Should Be Equal As Strings ${resp.status_code} 200 + [Return] ${resp} + + diff --git a/ric_robot_suite/helm/nanobot/configmap-src/public/resources/dbaas_interface.robot b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/dbaas_interface.robot new file mode 100644 index 0000000..4ce3bd9 --- /dev/null +++ b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/dbaas_interface.robot @@ -0,0 +1,42 @@ +# Copyright (c) 2020 HCL Technologies Limited. +# 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. + +*** Settings *** +Documentation Tests for the UE Event Collector XApp + +Resource /robot/resources/global_properties.robot +Resource /robot/resources/ric/ric_utils.robot + +Library String +Library Collections +Library XML + +Library KubernetesEntity ${GLOBAL_RICPLT_NAMESPACE} +Library SDLWrapper False +*** Variables *** + +*** Keywords *** +Run dbaas Health Check + [Documentation] Runs dbaas Health check + ${data_path} = Set Variable /v1/health + ${resp} = Run dbaas GET Request + +Run dbaas GET Request + ${c} = Get From Dictionary ${GLOBAL_RICPLT_COMPONENTS} dbaas + ${ctrl} ${dbaas1} = Split String ${c} | + ${deploy} = Run Keyword ${ctrl} ${dbaas1} + ${log} = Run Keyword healthcheck + Log To Console ${log} + Log ${log} console=yes + [Return] ${deploy} + diff --git a/ric_robot_suite/helm/nanobot/configmap-src/public/resources/e2mgr_interface.robot b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/e2mgr_interface.robot new file mode 100644 index 0000000..115f63a --- /dev/null +++ b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/e2mgr_interface.robot @@ -0,0 +1,135 @@ +# Copyright (c) 2019 AT&T Intellectual Property. +# Copyright (c) 2020 HCL Technologies Limited. +# 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. + +*** Settings *** +Documentation The main interface for interacting with RIC E2 Manager (E2Mgr). +... It handles low level stuff like managing the http request library and +... E2Mgr required fields +Library RequestsLibrary +Library UUID + +Resource /robot/resources/global_properties.robot +Resource /robot/resources/json_templater.robot + +*** Variables *** +${E2MGR_BASE_PATH} v1/nodeb +${E2MGR_ENDPOINT} ${GLOBAL_E2MGR_SERVER_PROTOCOL}://${GLOBAL_INJECTED_E2MGR_IP_ADDR}:${GLOBAL_E2MGR_SERVER_PORT} +${E2MGR_SETUP_NODEB_TEMPLATE} robot/assets/templates/e2mgr_setup_nodeb.template + + +** Keywords *** +Run E2Mgr Health Check + [Documentation] Runs E2Mgr Health check + ${data_path} = Set Variable /v1/health + ${resp} = Run E2Mgr GET Request ${data_path} + +Check NodeB Status + [Documentation] Check NodeB Status + [Arguments] ${ran_name} + ${resp} = Run E2Mgr Get NodeB Request ${ran_name} + Should Be Equal As Strings ${resp.json()['connectionStatus']} CONNECTED + [Return] ${resp} + +Run E2Mgr Get NodeB Request + [Documentation] Runs E2Mgr Get NodeB Request + [Arguments] ${ran_name} + ${data_path} = Set Variable ${E2MGR_BASE_PATH}/${ran_name} + ${resp} = Run E2Mgr GET Request ${data_path} + Should Be Equal As Strings ${resp.json()['ranName']} ${ran_name} + [Return] ${resp} + +Run E2Mgr Get All NodeBs Request + [Documentation] Runs E2Mgr Get All NodeBs Request + ${data_path} = Set Variable ${E2MGR_BASE_PATH}/ids + ${resp} = Run E2Mgr GET Request ${data_path} + [Return] ${resp} + +Run E2Mgr Setup NodeB X2 + [documentation] Setup X2 NodeB via E2 Manager + [Arguments] ${ran_name} ${ran_ip} ${ran_port} + ${data_path} = Set Variable ${E2MGR_BASE_PATH}/x2-setup + ${dict} = Create Dictionary + ... ran_name=${ran_name} + ... ran_ip=${ran_ip} + ... ran_port=${ran_port} + ${data} = Fill JSON Template File ${E2MGR_SETUP_NODEB_TEMPLATE} ${dict} + ${resp} = Run E2Mgr POST Request ${data_path} ${data} + [Return] ${resp} + +Run E2Mgr Setup NodeB Endc + [documentation] Setup Endc NodeB via E2 Manager + [Arguments] ${ran_name} ${ran_ip} ${ran_port} + ${data_path} = Set Variable ${E2MGR_BASE_PATH}/endc-setup + ${dict} = Create Dictionary ran_name=${ran_name} ran_ip=${ran_ip} ran_port=${ran_port} + ${data} = Fill JSON Template File ${E2MGR_SETUP_NODEB_TEMPLATE} ${dict} + ${resp} = Run E2Mgr POST Request ${data_path} ${data} + [Return] ${resp} + +Run E2Mgr Delete NodeB + [documentation] Delete NodeB via E2 Manager + [Arguments] ${ran_name} + ${data_path} = Set Variable ${E2MGR_BASE_PATH}/${ran_name} + ${resp} = Run E2Mgr DELETE Request ${data_path} + +# +Run E2Mgr GET Request + [Documentation] Runs E2Mgr GET Request + [Arguments] ${data_path} + ${auth} = Create List + ... ${GLOBAL_INJECTED_E2MGR_USER} + ... ${GLOBAL_INJECTED_E2MGR_PASSWORD} + ${session} = Create Session e2mgr ${E2MGR_ENDPOINT} auth=${auth} + ${uuid} = Generate UUID + ${headers} = Create Dictionary + ... Accept=application/json + ... Content-Type=application/json + ${resp} = Get Request e2mgr ${data_path} headers=${headers} + Log Received response from E2Mgr ${resp.text} + Should Be True ${resp} + [Return] ${resp} + +Run E2Mgr DELETE Request + [Documentation] Runs E2Mgr Delete Request + [Arguments] ${data_path} + ${auth} = Create List + ... ${GLOBAL_INJECTED_E2MGR_USER} + ... ${GLOBAL_INJECTED_E2MGR_PASSWORD} + ${session} = Create Session e2mgr ${E2MGR_ENDPOINT} auth=${auth} + ${uuid} = Generate UUID + ${headers} = Create Dictionary + ... Accept=application/json + ... Content-Type=application/json + ${resp} = Delete Request e2mgr ${data_path} headers=${headers} + Log Received response from E2Mgr ${resp.text} + Should Be True ${resp} + [Return] ${resp} + +Run E2Mgr POST Request + [Documentation] Send an HTTP POST to the E2 Manager + [Arguments] ${data_path} ${data} + ${auth} = Create List + ... ${GLOBAL_INJECTED_E2MGR_USER} + ... ${GLOBAL_INJECTED_E2MGR_PASSWORD} + ${session} = Create Session e2mgr ${E2MGR_ENDPOINT} auth=${auth} + ${headers} = Create Dictionary + ... Accept=application/json + ... Content-Type=application/json + ${resp} = Post Request e2mgr + ... ${data_path} + ... data=${data} + ... headers=${headers} + Log Received response from E2Mgr ${resp.text} + Should Be True ${resp} + [Return] ${resp} + diff --git a/ric_robot_suite/helm/nanobot/configmap-src/public/resources/e2term_interface.robot b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/e2term_interface.robot new file mode 100644 index 0000000..1dd4545 --- /dev/null +++ b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/e2term_interface.robot @@ -0,0 +1,35 @@ +*** Settings *** +Documentation The main interface for interacting with RIC E2 Term (E2term). +... It handles low level stuff like managing the http request library and +... E2term required fields +Library RequestsLibrary +Library UUID +Library Process +Library Collections +Library OperatingSystem + +Resource /robot/resources/global_properties.robot +Resource /robot/resources/json_templater.robot + + +*** Variables *** +${E2TERM_ENDPOINT} ${GLOBAL_INJECTED_E2TERM_IP_ADDR}:${GLOBAL_E2TERM_SERVER_PORT} + + +*** Keywords *** +Run E2Term Health Check + [Documentation] Runs E2Term Health check + Log To Console Entering in to E2term + ${data_path}= Set Variable ${E2TERM_ENDPOINT} + ${resp} = Run E2Term RMR Probe Check ${data_path} + Log To Console ${resp} + +Run E2Term RMR Probe Check + [Documentation] Runs E2Term RMR Probe Check + [Arguments] ${data_path} + + ${resp} = Run /bin/sh -c "/opt/e2/rmr_probe -h ${data_path} -v verbose" + Log To Console Received response from E2term ${resp} + ${ret} = Should Match Regexp ${resp} got.*OK.*state=0 + Log To Console ${ret} + [Return] ${ret} diff --git a/ric_robot_suite/helm/nanobot/configmap-src/public/resources/negative_appmgr_tests.robot b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/negative_appmgr_tests.robot new file mode 100644 index 0000000..3f69704 --- /dev/null +++ b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/negative_appmgr_tests.robot @@ -0,0 +1,38 @@ +*** settings *** +Documentation Negative tests for the AppMgr: ensure that AppMgr produces expected errors for a variety of invalid requests + +Library Collections +Library UUID + +Resource /robot/resources/global_properties.robot +Resource appmgr_interface.robot + +*** Keywords *** +Deploy Duplicate XApp And Expect Error + [Documentation] Ensure AppMgr produces an appropriate error when an already-running XApp is deployed + @{d} = Get Deployed XApps + Should Not Be Empty ${d} No XApps currently deployed + @{names} = Pluck name ${d} + ${xapp} = Evaluate random.choice(${names}) random + ${status} ${u} = Run Keyword And Ignore Error Deploy XApp ${xapp} + Should Be Equal As Strings ${status} FAIL + +Undeploy Nondeployed XApp And Expect Error + [Documentation] Ensure AppMgr produces an appropriate error when an existing but non-running XApp is deleted + @{d} = Get Deployed XApps + @{a} = Get Deployable XApps + Should Not Be Empty ${a} No XApps available to deploy + @{dNames} = Pluck name ${d} + @{a} = Subtract From List ${a} ${dNames} + Should Not Be Empty ${a} No undeployed XApps + ${xapp} = Evaluate random.choice(${a}) random + ${status} ${u} = Run Keyword And Ignore Error Undeploy XApp ${xapp} + Should Be Equal As Strings ${status} FAIL + +Request Nonexistent XApp And Expect Error + [Documentation] Ensure AppMgr produces an appropriate error when retrieving a nonexistent XApp + ${xapp} = Generate UUID + ${status} ${u} = Run Keyword And Ignore Error Get XApp By Name {$xapp} + Should Be Equal As Strings ${status} FAIL + + diff --git a/ric_robot_suite/helm/nanobot/configmap-src/public/resources/o1mediator_interface.robot b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/o1mediator_interface.robot new file mode 100644 index 0000000..0a4b04a --- /dev/null +++ b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/o1mediator_interface.robot @@ -0,0 +1,106 @@ +# Copyright (c) 2019 AT&T Intellectual Property. +# Copyright (c) 2020 HCL Technologies Limited. +# 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. + +*** Settings *** +Library XML use_lxml=True +Library NcclientLibrary + +Resource /robot/resources/global_properties.robot +Resource /robot/resources/ric/ric_utils.robot + +*** Variables *** +${XAppNS} urn:o-ran:ric:xapp-desc:1.0 +${NetconfNS} urn:ietf:params:xml:ns:netconf:base:1.0 +${ricXML} = +${configXML} ${ricXML} +${O1MEDIATOR_ENDPOINT} ${GLOBAL_O1MEDIATOR_SERVER_PROTOCOL}://${GLOBAL_O1MEDIATOR_HTTP_SERVER}:${GLOBAL_O1MEDIATOR_SERVER_PORT} + +*** Keywords *** +Run o1mediator Health Check + [Documentation] Runs O1Mediator Health check + ${resp} = Run Keyword Run o1mediator GET Request + +Run o1mediator GET Request + [Documentation] Make an HTTP GET request against the XApp manager + [Arguments] ${path}=${EMPTY} + ${session} = Create Session roboo1mediatorGet ${O1MEDIATOR_ENDPOINT} + ${headers} = Create Dictionary Accept=application/json Content-Type=application/json + ${resp} = Get Request roboo1mediatorGet ${O1MEDIATOR_ENDPOINT} headers=${headers} + [Return] ${resp} + + +Establish O1 Session + [Arguments] ${user} + ... ${password} + ... ${session} + ... ${host}=service-ricplt-o1mediator-tcp-netconf.ricplt + ... ${port}=830 + ... ${hostkey_verify}=${False} + ... ${key}=/dev/null + ${status} = Connect host=${host} + ... port=${port} + ... username=${user} + ... password=${password} + ... key_filename=${key} + ... look_for_keys=False + ... alias=${session} + [Return] ${status} + +Retrieve O1 State + [Arguments] ${session} + # this doesn't actually seem to result in filtered XML, + # but it matches what the O1 CLI does. + ${filter} = Parse XML ${ricXML} + ${config} = Get ${session} filter_criteria=${filter} + [Return] ${config} + +Retrieve O1 Running Configuration + [Arguments] ${session} + ${config} = Get Config ${session} running + [Return] ${config} + +Deploy An XApp Using O1 + [Arguments] ${session} ${app} ${version} + ${xappCreateXML} = Generate XApp Deployment XML ${app} ${version} create + Edit Config ${session} running ${xappCreateXML} + +Remove An XApp Using O1 + [Arguments] ${session} ${app} ${version} + ${xappDeleteXML} = Generate XApp Deployment XML ${app} ${version} delete + Edit Config ${session} running ${xappDeleteXML} + +Close O1 Session + [Arguments] ${session} + Close Session ${session} + +*** Keywords *** +Generate XApp Deployment XML + [Arguments] ${name} ${version} ${operation} + ${XML} = Parse XML ${configXML} + Add Element ${XML} + ... + ... xpath=ric + Add Element ${XML} + ... xpath=ric/xapps + Add Element ${XML} + ... ${name} + ... xpath=ric/xapps/xapp + Add Element ${XML} xapp-${name} + ... xpath=ric/xapps/xapp + Add Element ${XML} ${version} + ... xpath=ric/xapps/xapp + Add Element ${XML} ${GLOBAL_XAPP_NAMESPACE} + ... xpath=ric/xapps/xapp + [Return] ${XML} + diff --git a/ric_robot_suite/helm/nanobot/configmap-src/public/resources/ric_utils.robot b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/ric_utils.robot new file mode 100644 index 0000000..e704150 --- /dev/null +++ b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/ric_utils.robot @@ -0,0 +1,115 @@ +# Copyright (c) 2019 AT&T Intellectual Property. +# Copyright (c) 2020 HCL Technologies. +# 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. + +*** Settings *** +Documentation A library of utility keywords that may be useful +... in various test suites. + +Library Collections + +*** Keywords *** +# +# Kubernetes Utilities +Most Recent Availability Condition + # this makes the probably-unsafe assumption that the conditions are ordered + # temporally. + [Arguments] @{Conditions} + ${status} = Set Variable 'False' + FOR ${Condition} IN @{Conditions} + ${status} = Set Variable If '${Condition.type}' == 'Available' ${Condition.status} ${status} + END + [Return] ${status} + +Replica Availability + # this makes the probably-unsafe assumption that the conditions are ordered + # temporally. + [Arguments] ${Replica} + ${status} = Set Variable If ${Replica} >= 1 'True' 'False' + [Return] ${status} + +Most Recent Container Logs + [Arguments] ${deployment} ${container}=${EMPTY} ${regex}=${EMPTY} + ${pods} = Retrieve Pods For Deployment ${deployment} + ${logs} = Create List + FOR ${pod} IN @{pods} + ${log} = Retrieve Log For Pod ${pod} ${container} + Should Not Be Empty ${log} No log entries for ${pod}/${container} + ${line} = Run Keyword If "${regex}" != "${EMPTY}" + ... Most Recent Match ${log} ${regex} + ... ELSE + ... Get From List ${log} -1 + Append To List ${logs} ${line} + END + [Return] ${logs} + +Component Should Be Ready + [Documentation] Given a Kubernetes controller object as returned from the KubernetesEntity + ... library routines (such as 'Deployment' or Statefulset'), check whether the + ... entity is ready + [Arguments] ${entity} + Should Be Equal ${entity.status.replicas} ${entity.status.ready_replicas} + # This doesn't seem to make sense for statefulsets + ${status} = Run Keyword If '${entity.kind}' == 'Deployment' + ... Most Recent Availability Condition @{entity.status.conditions} + ... ELSE + ... Set Variable True + Should Be Equal As Strings ${status} True ignore_case=True + [Return] ${status} + +# +# Robot metatools +Run Keyword If Present + [Documentation] Run the given keyword, ignoring errors and returning status, if it exists. + ... Returns "PASS" if the keyword does not exist. + [Arguments] ${kw} + ${exists} ${u} = Run Keyword And Ignore Error + ... Keyword Should Exist ${kw} + ${status} ${u} = Run Keyword If '${exists}' == 'PASS' + ... Run Keyword And Ignore Error ${kw} + ... ELSE + ... Set Variable PASS unused + [Return] ${status} + +# +# Data manipulation +Toggle Flag + [Documentation] Apply "not" to a boolean flag + [Arguments] ${flag} + ${bFlag} = Convert To Boolean ${flag} + ${bFlag} = Set Variable If ${bFlag} ${false} ${true} + [Return] ${bFlag} + +Most Recent Match + [Arguments] ${list} ${regex} + ${matches} = Get Matches ${list} regexp=${regex} + Should Not Be Empty ${matches} No log entries matching ${regex} + ${match} = Get From List ${matches} -1 + [Return] ${match} + +Pluck + [Documentation] Get the values of a specific key from a list of dictionaries + [Arguments] ${k} ${l} + @{names} = Evaluate filter(lambda v: v != None, [i.get('${k}', None) for i in ${l}]) + [Return] ${names} + +Subtract From List + [Documentation] Remove the elements of the second argument from the first + [Arguments] ${x} ${y} + ${diff} = Run Keyword If ${y} + ... Evaluate filter(lambda v: v not in ${y}, ${x}) + ... ELSE + ... Set Variable ${x} + [Return] ${diff} + + diff --git a/ric_robot_suite/helm/nanobot/configmap-src/public/resources/rtmgr_interface.robot b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/rtmgr_interface.robot new file mode 100644 index 0000000..9ce3e92 --- /dev/null +++ b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/rtmgr_interface.robot @@ -0,0 +1,53 @@ +*** Settings *** +Documentation The main interface for interacting with Routing Manager (RtMgr) . It handles low level stuff like managing the http request library and RtMgr required fields + + +Library String +Library Collections +Library XML +Library RequestsLibrary +Library UUID +Library Process +Library OperatingSystem + + + +Resource /robot/resources/global_properties.robot +Resource /robot/resources/json_templater.robot +Resource /robot/resources/ric/ric_utils.robot + +Library KubernetesEntity ${GLOBAL_RICPLT_NAMESPACE} + +*** Variables *** +${RTMGR_BASE_PATH} /ric/v1/health/alive + + + + +*** Keywords *** +Run RtMgr Health Check + [Documentation] Runs RtMgr Health check + ${data_path}= Set Variable ${RTMGR_BASE_PATH} + ${resp}= Run Keyword Run RtMgr Get Request ${data_path} + + +Run RtMgr Get Request + [Documentation] Runs RtMgr Get request + [Arguments] ${data_path} + ${auth}= Create List ${GLOBAL_INJECTED_RTMGR_USER} ${GLOBAL_INJECTED_RTMGR_PASSWORD} + ${c} = Get From Dictionary ${GLOBAL_RICPLT_COMPONENTS} rtmgr + Log To Console ${c} + ${ctrl} ${rtmgr1} = Split String ${c} | + ${name} = Run Keyword RetrievePodsForDeployment ${rtmgr1} + ${name1} = Set Variable ${name[0]} + ${cType} = Set Variable Pod + ${ctl} = Run Keyword ${ctype} ${name1} + ${podIP} = Set Variable ${ctl.status.pod_ip} + ${RTMGR_ENDPOINT}= Set Variable ${GLOBAL_RTMGR_SERVER_PROTOCOL}://${podIP}:${GLOBAL_RTMGR_SERVER_HTTP_PORT} + ${session}= Create Session rtmgr ${RTMGR_ENDPOINT} auth=${auth} + ${uuid}= Generate UUID + ${headers}= Create Dictionary Accept=application/json Content-Type=application/json + ${resp}= Get Request rtmgr ${data_path} headers=${headers} + Log Received response from RtMgr ${resp.text} + Should Be Equal As Strings ${resp.status_code} 200 + [Return] ${resp} diff --git a/ric_robot_suite/helm/nanobot/configmap-src/public/resources/submgr_interface.robot b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/submgr_interface.robot new file mode 100644 index 0000000..65722f4 --- /dev/null +++ b/ric_robot_suite/helm/nanobot/configmap-src/public/resources/submgr_interface.robot @@ -0,0 +1,47 @@ +*** Settings *** +Documentation Tests for the UE Event Collector XApp + +Resource /robot/resources/global_properties.robot +Resource /robot/resources/ric/ric_utils.robot +Resource /robot/resources/json_templater.robot + +Library String +Library Collections +Library XML +Library RequestsLibrary +Library UUID +Library Process +Library OperatingSystem + +Library KubernetesEntity ${GLOBAL_RICPLT_NAMESPACE} + +*** Variables *** +${SUBMGR_BASE_PATH} /ric/v1/health/alive + + +*** Keywords *** +Run submgr Health Check + [Documentation] Runs SubMgr Health check + ${data_path}= Set Variable ${SUBMGR_BASE_PATH} + ${resp} = Run Keyword Run submgr GET Request ${data_path} + +Run submgr GET Request + [Documentation] Make an HTTP GET request against the submgr + [Arguments] ${data_path} + ${auth}= Create List ${GLOBAL_INJECTED_SUBMGR_USER} ${GLOBAL_INJECTED_SUBMGR_PASSWORD} + ${c} = Get From Dictionary ${GLOBAL_RICPLT_COMPONENTS} submgr + ${ctrl} ${submgr1} = Split String ${c} | + ${name} = Run Keyword RetrievePodsForDeployment ${submgr1} + ${name1} = Set Variable ${name[0]} + ${cType} = Set Variable Pod + ${ctrl1} = Run Keyword ${cType} ${name1} + ${podIP} = Set Variable ${ctrl1.status.pod_ip} + Log To Console ${podIP} + ${SUBMGR_ENDPOINT}= Set Variable ${GLOBAL_SUBMGR_SERVER_PROTOCOL}://${podIP}:${GLOBAL_SUBMGR_SERVER_PORT} + ${session}= Create Session robosubmgr ${SUBMGR_ENDPOINT} auth=${auth} + ${uuid}= Generate UUID + ${headers}= Create Dictionary Accept=application/json Content-Type=application/json + ${resp}= Get Request robosubmgr ${data_path} headers=${headers} + Log Received response from SubMgr ${resp.text} + Should Be Equal As Strings ${resp.status_code} 200 + [Return] ${resp} diff --git a/ric_robot_suite/helm/nanobot/configmap-src/public/testsuites/ete.robot b/ric_robot_suite/helm/nanobot/configmap-src/public/testsuites/ete.robot index 35d12a3..b72bd1f 100644 --- a/ric_robot_suite/helm/nanobot/configmap-src/public/testsuites/ete.robot +++ b/ric_robot_suite/helm/nanobot/configmap-src/public/testsuites/ete.robot @@ -1,4 +1,5 @@ # Copyright (c) 2019 AT&T Intellectual Property. +# Copyright (c) 2020 HCL Technologies Limited. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,73 +12,153 @@ # 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. - + *** Settings *** -Documentation Executes the End To End Test cases +Documentation Executes the End To End Test cases ... +Resource /robot/resources/appmgr_interface.robot +Resource /robot/resources/negative_appmgr_tests.robot +Resource /robot/resources/e2mgr_interface.robot +Resource /robot//resources/dashboard_interface.robot +Resource /robot/resources/global_properties.robot +Resource /robot/resources/ric/ric_utils.robot + + Library Collections Library OperatingSystem - -Resource ../resources/appmgr/appmgr_interface.robot -Resource ../resources/appmgr/negative_appmgr_tests.robot -Resource ../resources/e2mgr/e2mgr_interface.robot -Resource ../resources/dashboard/dashboard_interface.robot - +Library RequestsLibrary +Library KubernetesEntity ${GLOBAL_RICPLT_NAMESPACE} +Library String *** Variables *** ${TEST_XAPPNAME} ${GLOBAL_TEST_XAPP} ${TEST_NODE_B_NAME} ${GLOBAL_TEST_NODEB_NAME} ${TEST_NODE_B_IP} ${GLOBAL_TEST_NODEB_ADDRESS} ${TEST_NODE_B_PORT} ${GLOBAL_TEST_NODEB_PORT} - - +${ricxapp_POD_NAME} ${GLOBAL_XAPP_NAMESPACE}-${GLOBAL_XAPP} +${TEST_XAPP_ONBOARDER} ${GLOBAL_TEST_XAPP_ONBOARDER} *** Test Cases *** Test XApp Manager Health [Tags] etetests xapptests Run AppMgr Health Check -Deploy An XApp + +Ensure RIC Xapp Onboarder is deployed and available + [Tags] etetests xapptests + ${controllerName} = Set Variable ${GLOBAL_TEST_XAPP_ONBOARDER} + ${cType} ${name} = split String ${controllerName} | + ${ctrl} = Run Keyword ${cType} ${name} + Should Be Equal ${ctrl.status.replicas} ${ctrl.status.ready_replicas} + +Ensure E2Sim is deployed and available + [Tags] etetests xapptests + ${ctrl} = Run Keyword deployment ${Global_RAN_DEPLOYMENT} ${Global_RAN_NAMESPACE} + Should Be Equal ${ctrl.status.replicas} ${ctrl.status.ready_replicas} + +#Before doing this kept configfile.json in to shared path and create url +#onboard the xapp using onboard link +Deploy An XApp [Tags] etetests xapptests intrusive Deploy XApp ${TEST_XAPPNAME} + Retrieve The Deployed XApp [Tags] etetests xapptests Get XApp By Name ${TEST_XAPPNAME} + Attempt To Deploy A Duplicate XApp [Tags] etetests xapptests intrusive Deploy Duplicate XApp And Expect Error -Undeploy The Deployed XApp - [Tags] etetests xapptests intrusive - Undeploy XApp ${TEST_XAPPNAME} + Attempt To Undeploy An Already Undeployed XApp [Tags] etetests xapptests intrusive Undeploy Nondeployed XApp And Expect Error + Attempt To Request A Nonexistent XApp [Tags] etetests xapptests intrusive Request Nonexistent XApp And Expect Error - -Setup RAN Via E2Mgr X2 - [Tags] x2setup - Run E2Mgr Setup NodeB X2 ${TEST_NODE_B_NAME} ${TEST_NODE_B_IP} ${TEST_NODE_B_PORT} - Wait Until Keyword Succeeds 20s 5s Check NodeB Status ${TEST_NODE_B_NAME} -Setup RAN Via E2Mgr Endc - [Tags] e2setup - Run E2Mgr Setup NodeB Endc ${TEST_NODE_B_NAME} ${TEST_NODE_B_IP} ${TEST_NODE_B_PORT} - Wait Until Keyword Succeeds 20s 5s Check NodeB Status ${TEST_NODE_B_NAME} -Get NodeB via E2Mgr - [Tags] e2setup x2setup - Run E2Mgr Get NodeB Request ${TEST_NODE_B_NAME} + Get All NodeBs Via E2Mgr [Tags] e2mgrtest etetests e2setup x2setup ci_tests Run E2Mgr Get All NodeBs Request + +# disabled below 3 testcases due to x2 setup related APIs deprecated +# webservices interface specification deprecated +#Setup RAN Via E2Mgr X2 +#[Tags] disabled +##[Tags] e2setup x2setup +#Run E2Mgr Setup NodeB X2 ${TEST_NODE_B_NAME} ${TEST_NODE_B_IP} ${TEST_NODE_B_PORT} +#Wait Until Keyword Succeeds 20s 5s Check NodeB Status ${TEST_NODE_B_NAME} +#Setup RAN Via E2Mgr Endc +#[Tags] disabled +##[Tags] e2setup x2setup +#Run E2Mgr Setup NodeB Endc ${TEST_NODE_B_NAME} ${TEST_NODE_B_IP} ${TEST_NODE_B_PORT} +#Wait Until Keyword Succeeds 20s 5s Check NodeB Status ${TEST_NODE_B_NAME} +#Get NodeB via E2Mgr +#[Tags] disabled +#[Tags] e2setup x2setup +#Run E2Mgr Get NodeB Request ${TEST_NODE_B_NAME} + +###Not tested dashboard related Setup RAN Via Dashboard Endc [Tags] e2setup_dash Run Dashboard Setup NodeB Endc ${TEST_NODE_B_NAME} ${TEST_NODE_B_IP} ${TEST_NODE_B_PORT} Wait Until Keyword Succeeds 20s 5s Dashboard Check NodeB Status ${TEST_NODE_B_NAME} + Setup RAN Via Dashboard X2 [Tags] x2setup_dash Run Dashboard Setup NodeB X2 ${TEST_NODE_B_NAME} ${TEST_NODE_B_IP} ${TEST_NODE_B_PORT} Wait Until Keyword Succeeds 20s 5s Dashboard Check NodeB Status ${TEST_NODE_B_NAME} + Get NodeB via Dashboard [Tags] e2setup_dash x2setup_dash Run Dashboard Get NodeB Request ${TEST_NODE_B_NAME} + Get All NodeBs via Dashboard [Tags] e2setup_dash x2setup_dash ci_tests Run Dashboard Get All NodeBs Request +############### +Verifying E2setup Request From E2sim + [Tags] etetests xapptests + ${ric_xapp_pod} = Run Keyword RetrievePodsForDeployment ${ricxapp_POD_NAME} ${GLOBAL_XAPP_NAMESPACE} + ${ric_xapp_pod1} = Set Variable ${ric_xapp_pod[0]} + Set Global Variable ${ric_xapp_pod1} + ${e2simpod} = Run Keyword RetrievePodsForDeployment ${Global_RAN_DEPLOYMENT} ${Global_RAN_NAMESPACE} + ${e2simpod1} = Set Variable ${e2simpod[0]} + Set Global Variable ${e2simpod1} + ${setupres_recv} = Run kubectl logs ${e2simpod1} -n ${Global_RAN_NAMESPACE} | grep "SETUP" + Log To Console Subscription Received: ${setupres_recv} + Should Match Regexp ${setupres_recv} Received SETUP-RESPONSE-SUCCESS + +Verifying Subscription Request From Xapp + [Tags] etetests xapptests + sleep 100 + Log To Console "Sending Subscription Message from Xapp" + ${subname} = Run kubectl logs ${ric_xapp_pod1} -n ${GLOBAL_XAPP_NAMESPACE} | grep "Subscription SUCCESSFUL" + Should Match Regexp ${subname} Subscription.*SUCCESSFUL + ${sub_sent} = Run kubectl logs ${ric_xapp_pod1} -n ${GLOBAL_XAPP_NAMESPACE} | grep "Message Sent: RMR State = RMR_OK" + Log To Console Subscription Sent: ${sub_sent} + Should Match Regexp ${sub_sent} RMR_OK + +Verifying Subscription Response From E2sim + [Tags] etetests xapptests + Log To Console "Receiving Subscription Message from RAN" + ${subrcv} = Run kubectl logs ${ric_xapp_pod1} -n ${GLOBAL_XAPP_NAMESPACE} | grep "Received subscription message of type" + Log To Console Subscription Received: ${subrcv} + Should Match Regexp ${subrcv} Received subscription message + +Verifying Ric Indication From E2sim + [Tags] etetests xapptests + Log To Console "Sending Indication Message from E2sim" + ${indication_sent} = Run kubectl logs ${e2simpod1} -n ${Global_RAN_NAMESPACE} | grep "Indication" + Log To Console Sending Indication: ${indication_sent} + Should Match Regexp ${indication_sent} sending RIC Indication + +Verifying Ric Indication on Xapp + [Tags] etetests xapptests + Log To Console "Received Indication Message from RAN" + ${indication_rcv} = Run kubectl logs ${ric_xapp_pod1} -n ${GLOBAL_XAPP_NAMESPACE} | grep "Received indication message of type" + Log To Console Received Indication: ${indication_rcv} + Should Match Regexp ${indication_rcv} Received indication message + +Undeploy The Deployed XApp + [Tags] etetests xapptests intrusive + Undeploy XApp ${TEST_XAPPNAME} + diff --git a/ric_robot_suite/helm/nanobot/configmap-src/public/testsuites/health-check.robot b/ric_robot_suite/helm/nanobot/configmap-src/public/testsuites/health-check.robot index 59ed490..1a18d57 100644 --- a/ric_robot_suite/helm/nanobot/configmap-src/public/testsuites/health-check.robot +++ b/ric_robot_suite/helm/nanobot/configmap-src/public/testsuites/health-check.robot @@ -1,4 +1,5 @@ # Copyright (c) 2019 AT&T Intellectual Property. +# Copyright (c) 2020 HCL Technologies Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,32 +13,45 @@ # See the License for the specific language governing permissions and # limitations under the License. +*** Settings *** +Documentation Run basic health checks for all known components which have one + +Resource /robot/resources/global_properties.robot + +Resource /robot/resources/ric/ric_utils.robot + +Library KubernetesEntity ${GLOBAL_RICPLT_NAMESPACE} +Library Collections +Library String +Library Process +Library OperatingSystem + + +*** Test Cases *** +Basic Component Health Checks + [Documentation] For any defined RIC component with a health check keyword, + ... Run that keyword. "Health check" keywords have names of the + ... form "Run ${component} Health Check". + # This could have been entirely implemented in Helm; however, I wanted to + # allow for the possibility that it would be used (with some modification) + # by the ric-robot, which does not perform template expansion on testsuites. + [Tags] health + Set Test Variable ${finalStatus} PASS + FOR ${component} IN @{GLOBAL_RICPLT_COMPONENTS} + Log To Console component is ${component} + Run Keyword And Ignore Error + ... Import Resource /robot/resources/${component}_interface.robot + ${healthCheck} = Set Variable Run ${component} Health Check + ${status} = Run Keyword If Present ${healthCheck} + Log To Console ${healthcheck} + Log To Console ${status} + ${finalStatus} = Set Variable If '${status}' == 'FAIL' FAIL ${finalStatus} + Run Keyword If '${status}' == 'FAIL' + ... Log To Console ${component} is unhealthy + ... ELSE + ... Log To Console ${component} is healthy + Log To Console ----------------------------------------------------------------- + END + Run Keyword If '${finalStatus}' == 'FAIL' + ... Fail One or more Health Checks failed -*** Settings *** -Documentation Run basic health checks for all known components which have one - -Resource /robot/resources/global_properties.robot - -Resource /robot/resources/ric/ric_utils.robot - -*** Test Cases *** -Basic Component Health Checks - [Documentation] For any defined RIC component with a health check keyword, - ... Run that keyword. "Health check" keywords have names of the - ... form "Run ${component} Health Check". - # This could have been entirely implemented in Helm; however, I wanted to - # allow for the possibility that it would be used (with some modification) - # by the ric-robot, which does not perform template expansion on testsuites. - [Tags] health - Set Test Variable ${finalStatus} PASS - FOR ${component} IN @{GLOBAL_RICPLT_COMPONENTS} - Run Keyword And Ignore Error - ... Import Resource /robot/resources/${component}/${component}_interface.robot - ${healthCheck} = Set Variable Run ${component} Health Check - ${status} = Run Keyword If Present ${healthCheck} - ${finalStatus} = Set Variable If '${status}' == 'FAIL' FAIL ${finalStatus} - Run Keyword If '${status}' == 'FAIL' - ... Log ${component} is unhealthy - END - Run Keyword If '${finalStatus}' == 'FAIL' - ... Fail One or more Health Checks failed diff --git a/ric_robot_suite/helm/nanobot/configmap-src/public/testsuites/ricdeployment.robot b/ric_robot_suite/helm/nanobot/configmap-src/public/testsuites/ricdeployment.robot index 79c5e55..8bc53b6 100644 --- a/ric_robot_suite/helm/nanobot/configmap-src/public/testsuites/ricdeployment.robot +++ b/ric_robot_suite/helm/nanobot/configmap-src/public/testsuites/ricdeployment.robot @@ -12,8 +12,7 @@ # 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. - -*** Settings *** +***settings *** Documentation Tests for the existence and functionality of RIC components Resource /robot/resources/global_properties.robot @@ -24,12 +23,33 @@ Library KubernetesEntity ${GLOBAL_RICPLT_NAMESPACE} Library Collections Library String +*** Keywords *** +Assign True + [Return] True + +*** Variables **** +#&{GLOBAL_RICPLT_COMPONENTS} {dbaas = statefulset|statefulset-ricplt-dbaas} + *** Test Cases *** Ensure RIC components are deployed and available [Tags] etetests k8stests ci_tests FOR ${component} IN @{GLOBAL_RICPLT_COMPONENTS} ${controllerName} = Get From Dictionary ${GLOBAL_RICPLT_COMPONENTS} ${Component} ${cType} ${name} = Split String ${controllerName} | - ${ctrl} = Run Keyword ${cType} ${name} - Component Should Be Ready ${ctrl} + Log To Console ${cType} + ${ctrl} = Run Keyword ${cType} ${name} + Should Be Equal ${ctrl.status.replicas} ${ctrl.status.ready_replicas} + Log To Console ${Component} + #Log To Console ${cType} + # + + Log To Console ${ctrl.status} + ${status} = Run Keyword If '${cType}' == 'deployment' + ... Most Recent Availability Condition @{ctrl.status.conditions} + ... ELSE + ... Assign True + Log To Console ${status} + Log To Console ---------------------------- + Should Be Equal As Strings ${status} True ignore_case=True msg=${Component} is not available END + diff --git a/ric_robot_suite/helm/nanobot/templates/job-ric-robot-run.yaml b/ric_robot_suite/helm/nanobot/templates/job-ric-robot-run.yaml index c476853..a812055 100644 --- a/ric_robot_suite/helm/nanobot/templates/job-ric-robot-run.yaml +++ b/ric_robot_suite/helm/nanobot/templates/job-ric-robot-run.yaml @@ -1,13 +1,14 @@ {{/* Copyright (c) 2019 AT&T Intellectual Property. Copyright (c) 2019 Nokia. - + Copyright (c) 2020 HCL Technologies Limited. + 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. @@ -15,6 +16,7 @@ limitations under the License. */}} {{- $platformNamespace := include "common.namespace.platform" . }} +{{- $e2simNamespace := default "test"}} {{- $xappNamespace := include "common.namespace.xapp" . }} {{- $releaseName := default "ric-full" .Values.ric.platform.releaseName }} {{- $jobName := printf "%s-%s" .Release.Name $releaseName }} @@ -35,7 +37,7 @@ metadata: namespace: {{ $platformNamespace }} rules: - apiGroups: [""] - resources: ["pods", "services"] + resources: ["pods", "pods/log", "pods/exec", "services"] verbs: ["get", "list"] - apiGroups: ["apps"] resources: ["daemonsets", "replicasets", "statefulsets"] @@ -72,7 +74,7 @@ metadata: namespace: {{ $xappNamespace }} rules: - apiGroups: [""] - resources: ["pods", "pods/log", "services"] + resources: ["pods", "pods/log", "pods/exec", "services"] verbs: ["get", "list"] - apiGroups: ["apps"] resources: ["deployments", "daemonsets", "replicasets", "statefulsets"] @@ -94,7 +96,44 @@ subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ .Release.Namespace }} + {{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: Role +metadata: + name: {{ $serviceAccountName }}-{{ $releaseName }}-e2sim-access + namespace: {{ $e2simNamespace }} +rules: +- apiGroups: [""] + resources: ["pods", "pods/log", "pods/exec", "services"] + verbs: ["get", "list"] +- apiGroups: ["apps"] + resources: ["daemonsets", "replicasets", "statefulsets"] + verbs: ["get", "list"] +- apiGroups: ["extensions"] + resources: ["daemonsets", "replicasets"] + verbs: ["get", "list"] +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "list", "patch"] +- apiGroups: ["extensions"] + resources: ["deployments"] + verbs: ["get", "list", "patch"] +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: {{ $serviceAccountName }}-{{ $releaseName }}-e2sim-access + namespace: {{ $e2simNamespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ $serviceAccountName }}-{{ $releaseName }}-e2sim-access +subjects: + - kind: ServiceAccount + name: {{ $serviceAccountName }} + namespace: {{ .Release.Namespace }} {{- end }} --- apiVersion: batch/v1 @@ -153,6 +192,10 @@ spec: imagePullPolicy: {{ default "IfNotPresent" .pullPolicy }} {{- end }} env: + - name: DBAAS_SERVICE_HOST + value: "service-ricplt-dbaas-tcp.ricplt.svc.cluster.local" + - name: DBAAS_SERVICE_PORT + value: "6379" - name: RICPLT_NAMESPACE value: {{ $platformNamespace }} - name: RICPLT_RELEASE_NAME @@ -161,11 +204,13 @@ spec: value: {{ keys .Values.ric.platform.components | join " " }} - name: RICXAPP_NAMESPACE value: {{ $xappNamespace }} + - name: E2SIM_NAMESPACE + value: {{ $e2simNamespace }} - name: KUBECONFIG value: /robot/etc/ric-robot-kubeconfig.conf command: ["robot"] args: - - "-T" + - "-T" {{- if not .Values.ric.robot.job.failOnTestFail }} - "--NoStatusRC" {{- end }} @@ -226,7 +271,7 @@ spec: subPath: {{ base $map }} readOnly: true {{- end }} -{{- range $map, $ignore := $.Files.Glob "configmap-src/*/resources/*.robot" }} +{{- range $map, $ignore := $.Files.Glob "configmap-src/*/resources/*" }} - name: robot-resources mountPath: /robot/resources/{{ base $map }} subPath: {{ base $map }} @@ -257,3 +302,4 @@ spec: configMap: name: robot-resources defaultMode: 0644 + diff --git a/ric_robot_suite/helm/nanobot/values.yaml b/ric_robot_suite/helm/nanobot/values.yaml index c433c17..ebea4d0 100644 --- a/ric_robot_suite/helm/nanobot/values.yaml +++ b/ric_robot_suite/helm/nanobot/values.yaml @@ -1,6 +1,6 @@ # Copyright (c) 2019 AT&T Intellectual Property. # Copyright (c) 2019 Nokia. -# +# Copyright (c) 2020 HCL Technologies Limited. # 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 @@ -29,9 +29,10 @@ images: run: repository: nexus3.o-ran-sc.org:10004 name: o-ran-sc/it-test-nanobot - tag: 0.0.2 + tag: 0.0.3 + # note: the helm chart does not create repository credential secrets. - # If your repository requires authentication, create a docker-registry + # If your repository requires authentication, create a docker-registry # secret with # # kubectl create secret docker-registry --namespace ... @@ -61,14 +62,16 @@ ric: password: test dbaas: controller: + type: statefulset + suffix: server # the type of k8s controller for this entity # (ie, statefulset, daemonset, deployment..) # if unspecified, the default is "deployment". - type: statefulset + #type: statefulset # the suffix, if any, to append to the name # of the controller entity. The chart will # prepend a hyphen to this string. - suffix: server + # suffix: server e2mgr: user: test password: test @@ -79,6 +82,9 @@ ric: user: test password: test submgr: + user: test + password: test + port: 8080 o1mediator: user: test password: test @@ -98,19 +104,37 @@ ric: - throughput_gnb - throughput_rollup - throughput_ue + rbac: + # If true, create & use RBAC resources + # + create: true + clusterAdminRole: true + rules: + cluster: + - apiGroups: + - "" + resources: + - ["pods", "pods/log", "pods/exec", "services"] + verbs: + - get + - list + - watch + - patch + - update robot: release: r1 # # If specified, a host filesystem - # path where robot output will be stored + # path where robot output will be stored log: /opt/ric/robot/log # # Active testsuites can be chosen by # tag, testuite names, or both. leaving # either unspecified will cause all to run. testsuites: - # - ricdeployment - # - healthcheck + - ricdeployment + - health-check + - ete tags: enabled: # - etetests @@ -137,22 +161,27 @@ ric: create: true # ... and specify the serviceaccount here: # name: nanobot - # + # environment: # the name of a test xapp; the appmgr testsuite # will attempt to deploy and undeploy this app; # This should be an xapp which is "onboarded" to # the appmgr but not deployed at the time the test # is initiated. - xapp: robot-xapp + xapp: bouncerauto-xapp gNodeB: # the details of a test gNodeB, for [E/X]2 tests. # This can be either a real gnodeb or a simulator, # but in either case should exist prior to test # initiation. + # added deployment name and deployment namespace, + # for Ran elements. name: AAAA456789 address: 10.0.0.3 port: 36421 + ran_deployment: e2sim + ran_namespace: test dashboard: address: 10.1.0.1 - port: 31080 \ No newline at end of file + port: 31080 + diff --git a/ric_robot_suite/ric-python-utils/ricutils/KubernetesEntity.py b/ric_robot_suite/ric-python-utils/ricutils/KubernetesEntity.py index 049d17d..74bddb3 100644 --- a/ric_robot_suite/ric-python-utils/ricutils/KubernetesEntity.py +++ b/ric_robot_suite/ric-python-utils/ricutils/KubernetesEntity.py @@ -63,7 +63,7 @@ class KubernetesEntity(object): return self._k8sCore.read_namespaced_service(namespace=namespace or self._ns, name=name) - def Pod(self, name, namepsace=None): + def Pod(self, name, namespace=None): return self._k8sCore.read_namespaced_pod(namespace=namespace or self._ns, name=name)