+*.log
NOTES.txt
.pytest_cache/
xunit-results.xml
Testing locally
===============
-There are also two test receivers in ``localtests`` you can run locally.
+There are also two test receivers in ``integration_tests`` you can run locally.
The first is meant to be used with the ``control_admission`` policy
(that comes in test fixture ric manifest):
===================
This tests A1’s external API with two test receivers. Note, this
-currently depends on docker-compose, meaning you cannot run this if
-docker-compose is not installed. Note2: this is not fast. It builds the
-containers and launches requests against the API so it takes time.
+currently depends on helm+k8s, meaning you cannot run this if
+this is not installed.
+If you've never run the integration tests before, build the test receiver
+::
+
+ cd integration_tests
+ docker build --no-cache -t testreceiver:latest .
+
+Else, from the root,
::
tox -c tox-integration.ini
+This script:
+1. Deploys 3 helm charts into a local kubernetes installation
+2. Port forwards a pod ClusterIP to localhost
+3. Uses “tavern” to run some tests against the server
+4. Barrages the server with apache bench
+5. Tears everything down
+
+
Running
=======
K8S
---
-The helm chart is in the folder `a1mediator`.
-
-There are two files in `a1mediator/files` that should be replaced with the "real" files for deployment. The ones included there, and referenced in the configmap, are only samples. To deploy A1 correctly, make sure these files are correct.
+The "real" helm chart for A1 is in the LF it/dep repo. That repo holds all of the helm charts for the RIC platform. There is a helm chart in `integration_tests` here for running the integration tests as discussed above.
-::
-
- helm install --devel a1mediator/ --name a1 --set imageCredentials.username=xxx --set imageCredentials.password=xxx
-
-The username and password here are the credentials to the registry defined in `a1mediator/values.yaml`. Currently this is the LF docker registry.
-
-Docker
-------
+Local Docker
+------------
building
~~~~~~~~
-
::
docker build --no-cache -t a1:X.Y.Z .
running
~~~~~~~
-(TODO: this will be enhanced with Helm.)
-
::
docker run -dt -p 10000:10000 -v /path/to/localrt:/opt/route/local.rt -v /path/to/ricmanifest:/opt/ricmanifest.json a1:X.Y.Z -v
data:
local.rt: |
newrt|start
- rte|10000|rmr_delay_receiver:4563
- rte|20000|rmr_receiver:4560
+ rte|20000|testreceiverrmrservice:4560
+ rte|10000|delayreceiverrmrservice:4563
rte|10001|{{ .Values.rmrservice.name }}:{{ .Values.rmrservice.port }}
rte|20001|{{ .Values.rmrservice.name }}:{{ .Values.rmrservice.port }}
newrt|end
# This is the service for A1's external facing HTTP API
httpservice:
+ name: a1httpservice
port: 10000 # This is hardcoded in a1, probably dangerous to change
type: ClusterIP
# This is the service for rmr between A1 and the xapps
rmrservice:
- name: rmrservice
+ name: a1rmrservice
port: 4562 # This is hardcoded in a1, probably dangerous to change
type: ClusterIP
# This is the service for the "hidden" port 4561 that rmr listens on for route manager
rmrrtemgrservice:
- name: rmrrtemgrservice
+ name: a1rmrrtemgrservice
port: 4561 # This is hardcoded in rmr, probably dangerous to change
type: ClusterIP
--- /dev/null
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
--- /dev/null
+apiVersion: v1
+appVersion: "1.0"
+description: Test receiver for a1 integration tests
+name: delayreceiver
+version: 0.1.0
--- /dev/null
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "delayreceiver.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "delayreceiver.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "delayreceiver.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "delayreceiver.labels" -}}
+app.kubernetes.io/name: {{ include "delayreceiver.name" . }}
+helm.sh/chart: {{ include "delayreceiver.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
--- /dev/null
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: delayreceiverconf
+data:
+ local.rt: |
+ newrt|start
+ rte|10000|{{ .Values.rmrservice.name }}:{{ .Values.rmrservice.port }}
+ rte|10001|a1rmrservice:4562
+ newrt|end
+
--- /dev/null
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "delayreceiver.fullname" . }}
+ labels:
+{{ include "delayreceiver.labels" . | indent 4 }}
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: {{ include "delayreceiver.name" . }}
+ app.kubernetes.io/instance: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app.kubernetes.io/name: {{ include "delayreceiver.name" . }}
+ app.kubernetes.io/instance: {{ .Release.Name }}
+ spec:
+ containers:
+ - name: delayreceiver
+ image: testreceiver:latest
+ imagePullPolicy: Never
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ volumeMounts:
+ - name: delayreceiverconf
+ mountPath: /opt/route/local.rt
+ subPath: local.rt
+ env:
+ - name: RMR_RCV_RETRY_INTERVAL
+ value: "500"
+ - name: RMR_RETRY_TIMES
+ value: "10"
+ - name: TEST_RCV_PORT
+ value: "{{ .Values.rmrservice.port }}"
+ - name: TEST_RCV_RETURN_MINT
+ value: "10001"
+ - name: TEST_RCV_SEC_DELAY
+ value: "5"
+ - name: TEST_RCV_RETURN_PAYLOAD
+ value: '{"ACK_FROM": "DELAYED_TEST", "status": "SUCCESS"}'
+
+ volumes:
+ - name: "delayreceiverconf"
+ configMap:
+ name: "delayreceiverconf"
--- /dev/null
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.rmrservice.name }}
+ labels:
+{{ include "delayreceiver.labels" . | indent 4 }}
+spec:
+ type: {{ .Values.rmrservice.type }}
+ ports:
+ - port: {{ .Values.rmrservice.port }}
+ targetPort: {{ .Values.rmrservice.port }}
+ protocol: TCP
+ selector:
+ app.kubernetes.io/name: {{ include "delayreceiver.name" . }}
+ app.kubernetes.io/instance: {{ .Release.Name }}
--- /dev/null
+# Default values for delayreceiver.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+rmrservice:
+ name: delayreceiverrmrservice
+ type: ClusterIP
+ port: 4563
+
+ingress:
+ enabled: false
+ annotations: {}
+ # kubernetes.io/ingress.class: nginx
+ # kubernetes.io/tls-acme: "true"
+ hosts:
+ - host: chart-example.local
+ paths: []
+
+ tls: []
+ # - secretName: chart-example-tls
+ # hosts:
+ # - chart-example.local
+
+resources: {}
+ # We usually recommend not to specify default resources and to leave this as a conscious
+ # choice for the user. This also increases chances charts run on environments with little
+ # resources, such as Minikube. If you do want to specify resources, uncomment the following
+ # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+ # limits:
+ # cpu: 100m
+ # memory: 128Mi
+ # requests:
+ # cpu: 100m
+ # memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+++ /dev/null
-# ==================================================================================
-# Copyright (c) 2019 Nokia
-# Copyright (c) 2018-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.
-# ==================================================================================
-version: '3'
-services:
-
- rmr_receiver:
- build: .
- hostname: "rmr_receiver"
- volumes:
- - ./test_docker.rt:/opt/route/local.rt
-
- rmr_delay_receiver:
- build: .
- hostname: "rmr_delay_receiver"
- volumes:
- - ./test_docker.rt:/opt/route/local.rt
- environment:
- # https://github.com/docker/compose/issues/3878
- RMR_RCV_RETRY_INTERVAL: 500
- RMR_RETRY_TIMES: 10
- TEST_RCV_PORT: 4563
- TEST_RCV_RETURN_MINT: 10001
- TEST_RCV_SEC_DELAY: 5
- TEST_RCV_RETURN_PAYLOAD: '{"ACK_FROM": "DELAYED_TEST", "status": "SUCCESS"}'
+++ /dev/null
-# ==================================================================================
-# Copyright (c) 2019 Nokia
-# Copyright (c) 2018-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.
-# ==================================================================================
-version: '3'
-services:
-
- rmr_receiver:
- build: .
- hostname: "rmr_receiver"
- volumes:
- - ./test_docker.rt:/opt/route/local.rt
-
- rmr_delay_receiver:
- build: .
- hostname: "rmr_delay_receiver"
- volumes:
- - ./test_docker.rt:/opt/route/local.rt
- environment:
- # https://github.com/docker/compose/issues/3878
- RMR_RCV_RETRY_INTERVAL: 500
- RMR_RETRY_TIMES: 10
- TEST_RCV_PORT: 4563
- TEST_RCV_RETURN_MINT: 10001
- TEST_RCV_SEC_DELAY: 5
- TEST_RCV_RETURN_PAYLOAD: '{"ACK_FROM": "DELAYED_TEST", "status": "SUCCESS"}'
-
-# bombarder:
-# build:
-# context: .
-# dockerfile: Dockerfile-Bombard
-# hostname: "bombarder"
-# volumes:
-# - /tmp/local.rt:/opt/route/local.rt
-# environment:
-# BOMBARD_DELAY_MS: 100
-#
- a1:
- image: a1:latest
- build:
- context: ..
- hostname: "a1"
- volumes:
- - ./test_docker.rt:/opt/route/local.rt
- - ./../tests/fixtures/ricmanifest.json:/opt/ricmanifest.json
- - ./../tests/fixtures/rmr_string_int_mapping.txt:/opt/rmr_string_int_mapping.txt
- ports:
- - "10000:10000"
- environment:
- RMR_RCV_RETRY_INTERVAL: 500
- RMR_RETRY_TIMES: 20
--- /dev/null
+#!/bin/bash
+kubectl port-forward $(kubectl get pods --namespace default -l "app.kubernetes.io/name=a1mediator,app.kubernetes.io/instance=a1" -o jsonpath="{.items[0].metadata.name}") 10000:10000 2>&1 > forward.log &
+
+++ /dev/null
-newrt|start
-rte|10000|rmr_delay_receiver:4563
-rte|20000|rmr_receiver:4560
-rte|10001|a1:4562
-rte|20001|a1:4562
-newrt|end
--- /dev/null
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
--- /dev/null
+apiVersion: v1
+appVersion: "1.0"
+description: Test receiver for a1 integration tests
+name: testreceiver
+version: 0.1.0
--- /dev/null
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "testreceiver.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "testreceiver.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "testreceiver.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "testreceiver.labels" -}}
+app.kubernetes.io/name: {{ include "testreceiver.name" . }}
+helm.sh/chart: {{ include "testreceiver.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
--- /dev/null
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: testreceiverconf
+data:
+ local.rt: |
+ newrt|start
+ rte|20000|{{ .Values.rmrservice.name }}:{{ .Values.rmrservice.port }}
+ rte|20001|a1rmrservice:4562
+ newrt|end
+
--- /dev/null
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "testreceiver.fullname" . }}
+ labels:
+{{ include "testreceiver.labels" . | indent 4 }}
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: {{ include "testreceiver.name" . }}
+ app.kubernetes.io/instance: {{ .Release.Name }}
+ template:
+ metadata:
+ labels:
+ app.kubernetes.io/name: {{ include "testreceiver.name" . }}
+ app.kubernetes.io/instance: {{ .Release.Name }}
+ spec:
+ containers:
+ - name: testreceiver
+ image: testreceiver:latest
+ imagePullPolicy: Never
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ volumeMounts:
+ - name: testreceiverconf
+ mountPath: /opt/route/local.rt
+ subPath: local.rt
+ volumes:
+ - name: "testreceiverconf"
+ configMap:
+ name: "testreceiverconf"
--- /dev/null
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ .Values.rmrservice.name }}
+ labels:
+{{ include "testreceiver.labels" . | indent 4 }}
+spec:
+ type: {{ .Values.rmrservice.type }}
+ ports:
+ - port: {{ .Values.rmrservice.port }}
+ targetPort: {{ .Values.rmrservice.port }}
+ protocol: TCP
+ selector:
+ app.kubernetes.io/name: {{ include "testreceiver.name" . }}
+ app.kubernetes.io/instance: {{ .Release.Name }}
--- /dev/null
+# Default values for testreceiver.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+rmrservice:
+ name: testreceiverrmrservice
+ type: ClusterIP
+ port: 4560
+
+ingress:
+ enabled: false
+ annotations: {}
+ # kubernetes.io/ingress.class: nginx
+ # kubernetes.io/tls-acme: "true"
+ hosts:
+ - host: chart-example.local
+ paths: []
+
+ tls: []
+ # - secretName: chart-example-tls
+ # hosts:
+ # - chart-example.local
+
+resources: {}
+ # We usually recommend not to specify default resources and to leave this as a conscious
+ # choice for the user. This also increases chances charts run on environments with little
+ # resources, such as Minikube. If you do want to specify resources, uncomment the following
+ # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+ # limits:
+ # cpu: 100m
+ # memory: 128Mi
+ # requests:
+ # cpu: 100m
+ # memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
[testenv:int]
whitelist_externals=
sleep
- docker-compose
+ helm
ab
+ echo
+ pkill
+passenv = *
deps =
- pytest-xdist
tavern
changedir=integration_tests
commands_pre=
- docker-compose up --build -d
+ helm install --devel testreceiver -n testreceiver
+ helm install --devel delayreceiver -n delayreceiver
+ helm install --devel a1mediator/ -n a1
+ sleep 10
+ ./portforward.sh
sleep 2
commands=
-# helm lint a1mediator/
- pytest -n 2
+ echo "linting"
+ helm lint a1mediator/
+ echo "running tavern"
+ pytest
+ echo "running ab"
ab -n 100 -c 10 -u putdata -T application/json http://localhost:10000/ric/policies/control_admission_time
commands_post=
- docker-compose down
+ helm delete testreceiver
+ helm del --purge testreceiver
+ helm delete delayreceiver
+ helm del --purge delayreceiver
+ helm delete a1
+ helm del --purge a1
+ pkill -9 kubectl
+ sleep 10