+# 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.
+
{{- $domain := default "cluster.local" .Values.ric.cluster.domain }}
{{- $ricpltNS := include "common.namespace.platform" . }}
{{- $xappNS := include "common.namespace.xapp" . }}
${GLOBAL_APPLICATION_ID} {{ default "r0" .Values.ric.robot.release | printf "nanobot-%s" }}
${GLOBAL_BUILD_NUMBER} {{ default "0" .Values.ric.platform.build }}
${GLOBAL_RICPLT_NAMESPACE} {{ $ricpltNS }}
+${GLOBAL_XAPP_NAMESPACE} {{ $xappNS }}
#
+{{- if .Values.ric.platform.components.appmgr }}
${GLOBAL_APPMGR_SERVER_PROTOCOL} {{ default "http" .Values.ric.platform.components.appmgr.protocol }}
${GLOBAL_INJECTED_APPMGR_IP_ADDR} {{ printf "%s.%s" (include "common.servicename.appmgr.http" .) $ricplt }}
${GLOBAL_APPMGR_SERVER_PORT} {{ include "common.serviceport.appmgr.http" . }}
${GLOBAL_INJECTED_APPMGR_USER} {{ .Values.ric.platform.components.appmgr.user }}
${GLOBAL_INJECTED_APPMGR_PASSWORD} {{ .Values.ric.platform.components.appmgr.password }}
+{{- end }}
#
+{{- if .Values.ric.platform.components.e2mgr }}
${GLOBAL_E2MGR_SERVER_PROTOCOL} {{ default "http" .Values.ric.platform.components.e2mgr.protocol }}
${GLOBAL_INJECTED_E2MGR_IP_ADDR} {{ printf "%s.%s" (include "common.servicename.e2mgr.http" .) $ricplt }}
${GLOBAL_E2MGR_SERVER_PORT} {{ include "common.serviceport.e2mgr.http" . }}
${GLOBAL_INJECTED_E2MGR_USER} {{ .Values.ric.platform.components.e2mgr.user }}
${GLOBAL_INJECTED_E2MGR_PASSWORD} {{ .Values.ric.platform.components.e2mgr.password }}
+{{- 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_INJECTED_RTMGR_USER} {{ .Values.ric.platform.components.rtmgr.user }}
${GLOBAL_INJECTED_RTMGR_PASSWORD} {{ .Values.ric.platform.components.rtmgr.password }}
+{{- end }}
#
${GLOBAL_INJECTED_DBAAS_IP_ADDR} {{ printf "%s.%s" (include "common.servicename.dbaas.tcp" .) $ricplt }}
${GLOBAL_DBAAS_SERVER_PORT} {{ include "common.serviceport.dbaas.tcp" . }}
#
${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 }}
-${GLOBAL_TEST_NODEB_PORT} {{ default "36421" .Values.ric.robot.environment.gNodeB.port }}
\ No newline at end of file
+${GLOBAL_TEST_NODEB_PORT} {{ default "36421" .Values.ric.robot.environment.gNodeB.port }}
+#
+${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 }}
--- /dev/null
+# 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.
+
+*** Settings ***
+Documentation This file contains configuration specific to the MC xapp.
+
+*** Variables ***
+${GLOBAL_MCXAPP_LISTENER_NAME} {{ default "mc-xapp-listener" .Values.ric.xapp.mcxapp.listener.containername }}
+${GLOBAL_MCXAPP_WRITER_NAME} {{ default "mc-xapp-writer" .Values.ric.xapp.mcxapp.writer.containername }}
+@{GLOBAL_MCXAPP_WRITER_STATISTICS} {{- range .Values.ric.xapp.mcxapp.writer.statistics }}
+... {{.}}
+ {{- end }}
+# 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.
+
*** Settings ***
Documentation Executes the End To End Test cases
...
+# 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.
+
+
*** Settings ***
-Documentation Testing RIC components are available via calls.
-...
-... Testing RIC components are available via calls.
-Test Timeout 10 second
-Resource ../resources/appmgr/appmgr_interface.robot
-Resource ../resources/e2mgr/e2mgr_interface.robot
-Resource ../resources/rtmgr/rtmgr_interface.robot
+Documentation Run basic health checks for all known components which have one
-*** Test Cases ***
-Basic AppMgr Health Check
- [Tags] health
- Run AppMgr Health Check
-Basic E2Mgr Health Check
- [Tags] health
- Run E2Mgr Health Check
-Basic RtMgr Health Check
- [Tags] health
- Run RtMgr Health Check
+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
+ Run Keyword If '${finalStatus}' == 'FAIL'
+ ... Fail One or more Health Checks failed
--- /dev/null
+# 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.
+
+*** Settings ***
+Documentation Tests for the Measurement Campaign XApp
+
+
+Resource /robot/resources/global_properties.robot
+Resource /robot/resources/mcxapp_properties.robot
+
+Resource /robot/resources/ric/ric_utils.robot
+
+Library Collections
+Library KubernetesEntity ${GLOBAL_XAPP_NAMESPACE}
+
+*** Variables ***
+${listenerContainerName} mc-xapp-listener
+${listenerStatRegex} ^[0-9]+\\s*\\[STAT\\]\\s*\\(mcl\\)
+${recentListenerDrops} .*last 60s.*drops\\s*=\\s*([1-9][0-9]*)
+${recentListenerErrors} .*last 60s.*errs\\s*=\\s*([1-9][0-9]*)
+${writerVesSuccesses} .*successful\\s+ves\\s+posts\\s*-\\s*([1-9][0-9]*)
+${writerVesErrors} .*failed\\s+ves\\s+posts\\s*-\\s*([1-9][0-9]*)
+
+*** Test Cases ***
+XApp Should Be Available
+ [Tags] etetests xapptests mcxapptests
+ ${deploymentName} = Get From Dictionary ${GLOBAL_RICPLT_XAPPS} mcxapp
+ Set Suite Variable ${deploymentName}
+ ${deploy} = Deployment ${deploymentName}
+ ${status} = Most Recent Availability Condition @{deploy.status.conditions}
+ Should Be Equal As Strings ${status} True ignore_case=True
+
+Listener Should Not Be Dropping Messages
+ [Tags] etetests xapptests mcxapptests
+ ${log} = Most Recent Container Logs ${deploymentName}
+ ... ${GLOBAL_MCXAPP_LISTENER_NAME}
+ ... ${listenerStatRegex}
+ Should Not Contain Match ${log} regexp=${recentListenerDrops}
+
+Listener Should Not Be Producing Errors
+ [Tags] etetests xapptests mcxapptests
+ ${log} = Most Recent Container Logs ${deploymentName}
+ ... ${GLOBAL_MCXAPP_LISTENER_NAME}
+ ... ${listenerStatRegex}
+ Should Not Contain Match ${log} regexp=${recentListenerErrors}
+
+Writer Should Be Successfully Sending Statistics
+ [Tags] etetests xapptests mcxapptests
+ Set Test Variable ${finalStatus} PASS
+ :FOR ${stat} IN @{GLOBAL_MCXAPP_WRITER_STATISTICS}
+ \ ${statRE} = Regexp Escape ${stat}
+ \ ${log} = Most Recent Container Logs ${deploymentName}
+ ... ${GLOBAL_MCXAPP_WRITER_NAME}
+ ... ^${statRE}:\\s+successful\\s+ves\\s+posts\\.*
+ \ ${status} ${u} = Run Keyword And Ignore Error
+ ... Should Contain Match ${log} regexp=${writerVesSuccesses}
+ \ ${finalStatus} = Set Variable If "${status}" == "FAIL"
+ ... FAIL
+ ... ${finalStatus}
+ \ Run Keyword If "${status}" == "FAIL"
+ ... Log No messages have been sent to VES for ${stat}
+ \ ${status} ${u} = Run Keyword And Ignore Error
+ ... Should Not Contain Match ${log} regexp=${writerVesErrors}
+ \ ${finalStatus} = Set Variable If "${status}" == "FAIL"
+ ... FAIL
+ ... ${finalStatus}
+ \ Run Keyword If "${status}" == "FAIL"
+ ... Log ${stat} is producing errors logging to VES
+ Run Keyword If "${finalStatus}" == "FAIL"
+ ... Fail One or more statistics is not being succesfully logged
+
Resource /robot/resources/global_properties.robot
+Resource /robot/resources/ric/ric_utils.robot
+
Library KubernetesEntity ${GLOBAL_RICPLT_NAMESPACE}
Library Collections
Library String
\ ${deploy} = Deployment ${deploymentName}
\ ${status} = Most Recent Availability Condition @{deploy.status.conditions}
\ Should Be Equal As Strings ${status} True ignore_case=True msg=${Component} is not available
-
-*** Keywords ***
-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}
- [Return] ${status}
+# 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.
+
*** Settings ***
Documentation Initializes RIC Test Web Page and Password
namespace: {{ $xappNamespace }}
rules:
- apiGroups: [""]
- resources: ["pods", "services"]
+ resources: ["pods", "pods/log", "services"]
verbs: ["get", "list"]
- apiGroups: ["apps"]
resources: ["deployments", "daemonsets", "replicasets", "statefulsets"]
name: {{ $jobName }}-ric-robot-run
namespace: {{ .Release.Namespace }}
spec:
+ backoffLimit: {{ default 0 .Values.ric.robot.job.backoffLimit }}
template:
spec:
serviceAccountName: {{ $serviceAccountName }}
- restartPolicy: Never
+ restartPolicy: {{ default "Never" .Values.ric.robot.job.restartPolicy }}
initContainers:
- name: {{ $jobName }}-generate-robot-kubeconfig
{{ with .Values.images.ric.robot.job.init }}
# platform source tree
releaseName: r0
components:
+ a1mediator:
appmgr:
user: test
password: test
- rtmgr:
- user: test
- password: test
+ dbaas:
e2mgr:
user: test
password: test
e2term:
- a1mediator:
+ rtmgr:
+ user: test
+ password: test
+ submgr:
xapp:
- anr:
- servicename: anr
+ mcxapp:
+ listener:
+ containername: mc-xapp-listener
+ writer:
+ containername: mc-xapp-writer
+ # statistics sent to ves by the writer. the tests
+ # will check that these are actually being sent
+ statistics:
+ - mc_connected_cnt
+ - mc_connection_stats
+ - mc_connects_cnt
+ - mc_disconnects_cnt
+ - mc_unique_ue_cnt
+ - rrcx_pdf_serv_cell
+ - rrcx_pdf_serv_gnb
+ - rrcx_stats_serv_cell
+ - rrcx_stats_serv_gnb
robot:
release: r1
#
# set this to a true value to cause
# the job to fail (and, typically, be resubmitted)
# when tests fail
- failOnTestFail: false
+ failOnTestFail: true
serviceAccount:
# by default, the job will create
# a temporary serviceaccount and
name: AAAA456789
address: 10.0.0.3
port: 36421
+ dashboard:
+ address: 10.1.0.1
+ port: 31080
\ No newline at end of file
import string
import random
import time
+import sys
# This library provides a massively-simplified interface to the kubernetes
# API library to reduce bloat in robot tests.
timeout -= 1
raise TimeoutError('Kubernetes timeout waiting for ' + name + ' to become available')
+ def RetrievePodsForDeployment(self, name):
+ # return the pod names associated with a deployment
+ d = self.Deployment(name)
+ labels = d.spec.selector.match_labels
+ pods = self._k8sCore.list_namespaced_pod(self._ns,
+ label_selector=",".join(map(lambda k: k + "=" + labels[k],
+ labels)))
+ return map(lambda i: i.metadata.name, pods.items)
+
+ def RetrieveLogForPod(self, pod, container='', tail=sys.maxsize):
+ # not really an "entity" thing per se, but.
+ # kinda want to include timestamps, but i don't have a use case for them.
+ return self._k8sCore.read_namespaced_pod_log(namespace=self._ns,
+ name=pod,
+ container=container,
+ tail_lines=tail).split('\n')[0:-1]
Resource ../global_properties.robot
+Resource ../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}
${headers} = Create Dictionary Accept=application/json Content-Type=application/json
${resp} = Delete Request roboAppmgrDelete ${APPMGR_BASE_PATH}${path} headers=${headers}
[Return] ${resp}
-
-
-# a few useful list routines that should probably live elsewhere
-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}
--- /dev/null
+# 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.
+
+*** 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}
+ [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}
+ [Return] ${logs}
+
+#
+# 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}
--- /dev/null
+# 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.
+
+*** Settings ***
+Documentation This file contains configuration specific to the MC xapp.
+
+*** Variables ***
+${GLOBAL_MCXAPP_LISTENER_NAME} mc-xapp-listener
+${GLOBAL_MCXAPP_WRITER_NAME} mc-xapp-writer
+@{GLOBAL_MCXAPP_WRITER_STATISTICS}
+... mc_connected_cnt
+... mc_connection_stats
+... mc_connects_cnt
+... mc_disconnects_cnt
+... mc_unique_ue_cnt
+... rrcx_pdf_serv_cell
+... rrcx_pdf_serv_gnb
+... rrcx_stats_serv_cell
+... rrcx_stats_serv_gnb
--- /dev/null
+# 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.
+
+*** Settings ***
+Documentation Tests for the Measurement Campaign XApp
+
+Resource ../resources/xapps/mcxapp_properties.robot
+Resource ../resources/global_properties.robot
+
+Library Collections
+Library KubernetesEntity ${GLOBAL_XAPP_NAMESPACE}
+
+*** Variables ***
+${deploymentName} = ${GLOBAL_XAPP_NAMESPACE}-mcxapp
+${listenerContainerName} = mc-xapp-listener
+${listenerStatRegex} = ^[0-9]+\\s*\\[STAT\\]\\s*\\(mcl\\)
+${recentListenerDrops} = last 60s.*drops\\s*=\\s*[1-9]
+${recentListenerErrors} = last 60s.*errs\\s*=\\s*[1-9]
+
+*** Test Cases ***
+MC XApp Should Be Available
+ [Tags] etetests xapptests mcxapptests
+ ${deploy} = Deployment ${deploymentName}
+ ${status} = Most Recent Availability Condition @{deploy.status.conditions}
+ Should Be Equal As Strings ${status} True ignore_case=True
+
+MC XApp Listener Should Not Be Dropping Messages
+ [Tags] etetests xapptests mcxapptests
+ ${log} = Most Recent Container Log ${listenerContainerName} ${listenerStatRegex}
+ Should Not Contain Match ${log} ${recentListenerDrops}
+
+MC XApp Listener Should Not Be Producing Errors
+ [Tags] etetests xapptests mcxapptests
+ ${log} = Most Recent Container Log ${listenerContainerName} ${listenerStatRegex}
+ Should Not Contain Match ${log} ${recentListenerErrors}
+
+Writer Should Be Successfully Sending Statistics
+ [Tags] etetests xapptests mcxapptests
+ Set Test Variable ${finalStatus} PASS
+ :FOR ${stat} IN @{GLOBAL_MCXAPP_WRITER_STATISTICS}
+ \ ${statRE} = Regexp Escape ${stat}
+ \ ${log} = Most Recent Container Log
+ ... ${GLOBAL_MCXAPP_WRITER_NAME}
+ ... ^${statRE}:\\s+successful\\s+ves\\s+posts\\.*
+ \ ${status} ${u} = Run Keyword And Ignore Error
+ ... Should Contain Match ${log} regexp=${writerVesSuccesses}
+ \ ${finalStatus} = Set Variable If "${status}" == "FAIL"
+ ... FAIL
+ ... ${finalStatus}
+ \ Run Keyword If "${status}" == "FAIL"
+ ... Log No messages have been sent to VES for ${stat}
+ \ ${status} ${u} = Run Keyword And Ignore Error
+ ... Should Not Contain Match ${log} regexp=${writerVesErrors}
+ \ ${finalStatus} = Set Variable If "${status}" == "FAIL"
+ ... FAIL
+ ... ${finalStatus}
+ \ Run Keyword If "${status}" == "FAIL"
+ ... Log ${stat} is producing errors logging to VES
+ Run Keyword If "${finalStatus}" == "FAIL"
+ ... Fail One or more statistics is not being succesfully logged
+
+*** Keywords ***
+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}
+ [Return] ${status}
+
+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}
+
+Most Recent Container Log
+ [Arguments] ${container}=${EMPTY} ${regex}=${EMPTY}
+ ${pods} = Retrieve Pods For Deployment ${deploymentName}
+ ${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}
+ [Return] ${logs}
+
*** Settings ***
Documentation Tests for the existence and functionality of RIC components
-Resource /robot/resources/global_properties.robot
+Resource ../global_properties.robot
+
+Resource ../ric/ric_utils.robot
Library KubernetesEntity ${GLOBAL_RICPLT_NAMESPACE}
Library Collections
\ ${deploy} = Deployment ${deploymentName}
\ ${status} = Most Recent Availability Condition @{deploy.status.conditions}
\ Should Be Equal As Strings ${status} True ignore_case=True msg=${Component} is not available
-
-*** Keywords ***
-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}
- [Return] ${status}