2 # SPDX-license-identifier: Apache-2.0
3 ##############################################################################
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9 ##############################################################################
15 FUNCTIONS_DIR="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")"
17 source /etc/environment
21 local RED='\033[0;31m'
24 echo -e "${RED} $msg ---------------------------------------${NC}"
27 function get_ovn_central_address {
28 #Reuse OVN_CENTRAL_ADDRESS if available (bypassable by --force flag)
29 if [[ "${1:-}" != "--force" ]] && [[ -n "${OVN_CENTRAL_ADDRESS:-}" ]]; then
30 echo "${OVN_CENTRAL_ADDRESS}"
34 local remote_command="ip address show dev $OVN_CENTRAL_INTERFACE primary"
35 declare -a ansible_command=(ansible ovn-central[0] -i \
36 "${FUNCTIONS_DIR}/../hosting_providers/vagrant/inventory/hosts.ini")
37 declare -a filter=(awk -F '[ \t/]+' \
38 'BEGIN {r=1} {for (i=1; i<=NF; i++) if ($i == "inet") {print $(i+1); r=0}} END {exit r}')
41 #Determine OVN_CENTRAL_INTERFACE address
42 if ! result="$("${ansible_command[@]}" -a "${remote_command}")"; then
43 echo "Ansible error for remote host ovn-central[0]" >&2
46 if [[ "${result}" != *CHANGED* ]]; then
47 echo "Failed to execute command on remote host ovn-central[0]" >&2
50 if ! result="$("${filter[@]}" <<< "${result}")"; then
51 echo "Failed to retrieve interface address from command output" >&2
61 #Runs curl with passed flags and provides
62 #additional error handling and debug information
64 #Function outputs server response body
65 #and performs validation of http_code
68 local curl_response_file="$(mktemp -p /tmp)"
69 local curl_common_flags=(-s -w "%{http_code}" -o "${curl_response_file}")
70 local command=(curl "${curl_common_flags[@]}" "$@")
72 echo "[INFO] Running '${command[@]}'" >&2
73 if ! status="$("${command[@]}")"; then
74 echo "[ERROR] Internal curl error! '$status'" >&2
75 cat "${curl_response_file}"
76 rm "${curl_response_file}"
79 echo "[INFO] Server replied with status: ${status}" >&2
80 cat "${curl_response_file}"
81 rm "${curl_response_file}"
82 if [[ "${status:0:1}" =~ [45] ]]; then
90 function delete_resource {
91 #Issues DELETE http call to provided endpoint
92 #and further validates by following GET request
94 call_api -X DELETE "$1"
95 ! call_api -X GET "$1" >/dev/null
98 # init_network() - This function creates the OVN resouces required by the test
99 function init_network {
101 local router_name="ovn4nfv-master"
103 name=$(cat $fname | yq '.spec.name' | xargs)
104 subnet=$(cat $fname | yq '.spec.subnet' | xargs)
105 gateway=$(cat $fname | yq '.spec.gateway' | xargs)
106 ovn_central_address=$(get_ovn_central_address)
108 router_mac=$(printf '00:00:00:%02X:%02X:%02X' $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)))
109 ovn-nbctl --may-exist --db tcp:$ovn_central_address ls-add $name -- set logical_switch $name other-config:subnet=$subnet external-ids:gateway_ip=$gateway
110 ovn-nbctl --may-exist --db tcp:$ovn_central_address lrp-add $router_name rtos-$name $router_mac $gateway
111 ovn-nbctl --may-exist --db tcp:$ovn_central_address lsp-add $name stor-$name -- set logical_switch_port stor-$name type=router options:router-port=rtos-$name addresses=\"$router_mac\"
114 # cleanup_network() - This function removes the OVN resources created for the test
115 function cleanup_network {
118 name=$(cat $fname | yq '.spec.name' | xargs)
119 ovn_central_address=$(get_ovn_central_address)
121 for cmd in "ls-del $name" "lrp-del rtos-$name" "lsp-del stor-$name"; do
122 ovn-nbctl --if-exist --db tcp:$ovn_central_address $cmd
126 function _checks_args {
128 echo "Missing CSAR ID argument"
131 if [[ -z $CSAR_DIR ]]; then
132 echo "CSAR_DIR global environment value is empty"
135 mkdir -p ${CSAR_DIR}/${1}
138 # destroy_deployment() - This function ensures that a specific deployment is
139 # destroyed in Kubernetes
140 function destroy_deployment {
141 local deployment_name=$1
143 echo "$(date +%H:%M:%S) - $deployment_name : Destroying deployment"
144 kubectl delete deployment $deployment_name --ignore-not-found=true --now
145 while kubectl get deployment $deployment_name &>/dev/null; do
146 echo "$(date +%H:%M:%S) - $deployment_name : Destroying deployment"
150 # recreate_deployment() - This function destroys an existing deployment and
151 # creates an new one based on its yaml file
152 function recreate_deployment {
153 local deployment_name=$1
155 destroy_deployment $deployment_name
156 kubectl create -f $deployment_name.yaml
159 # wait_deployment() - Wait process to Running status on the Deployment's pods
160 function wait_deployment {
161 local deployment_name=$1
164 while [[ $status_phase != "Running" ]]; do
165 new_phase=$(kubectl get pods | grep $deployment_name | awk '{print $3}')
166 if [[ $new_phase != $status_phase ]]; then
167 echo "$(date +%H:%M:%S) - $deployment_name : $new_phase"
168 status_phase=$new_phase
170 if [[ $new_phase == "Err"* ]]; then
176 # wait_for_pod() - Wait until first pod matched by kubectl filters is in running status
177 function wait_for_pod {
179 # wait_for_pods example_pod
180 # wait_for_pods --namespace test different_pod
181 # wait_for_pods -n test -l app=plugin_test
184 while [[ "$status_phase" != "Running" ]]; do
185 new_phase="$(kubectl get pods -o 'go-template={{ index .items 0 "status" "phase" }}' "$@" )"
186 if [[ "$new_phase" != "$status_phase" ]]; then
187 echo "$(date +%H:%M:%S) - Filter=[$*] : $new_phase"
188 status_phase="$new_phase"
190 if [[ "$new_phase" == "Err"* ]]; then
196 # setup() - Base testing setup shared among functional tests
198 if ! $(kubectl version &>/dev/null); then
199 echo "This funtional test requires kubectl client"
202 for deployment_name in $@; do
203 recreate_deployment $deployment_name
206 for deployment_name in $@; do
207 wait_deployment $deployment_name
211 # teardown() - Base testing teardown function
213 for deployment_name in $@; do
214 destroy_deployment $deployment_name
217 test_folder=${FUNCTIONS_DIR}