Skip to content

Commit

Permalink
Zoning E2E Test + E2E Improvements (#818)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristianAtDell authored Dec 10, 2024
1 parent 6e3737c commit b734947
Show file tree
Hide file tree
Showing 13 changed files with 573 additions and 210 deletions.
26 changes: 16 additions & 10 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ go get github.com/onsi/gomega/...

For PowerFlex, Unity, PowerScale, PowerStore, Authorization, and Application-Mobility, system-specific information (array login credentials, system IDs, endpoints, etc.) need to be provided in e2e/array-info.sh so that all the required resources (secrets, storageclasses, etc.) can be created by the tests. Example values have been inserted; please replace these with values from your system. Refer to [CSM documentation](https://dell.github.io/csm-docs/docs/) for any further questions about driver or module pre-requisites.

In the case of end-to-end tests that involve PowerFlex zoning functionality, a second PowerFlex array will be necessary with its credentials provided in e2e/array-info.sh.

Please note that, if tests are stopped in the middle of a run, some files in `testfiles/*-templates` folders may remain in a partially modified state and break subsequent test runs. To undo these changes, you can run `git checkout -- <template file>`.

### Application Mobility Prerequisites
Expand Down Expand Up @@ -138,15 +140,15 @@ An e2e test scenarios file is a yaml file that defines all e2e test scenarios to
- "Enable forceRemoveDriver on CR"
- "Delete resources"
customTest:
# name of custom test to run
name: Cert CSI
# Provide command-line argument to run. Ginkgo will run the command and return output
# The command should be accessible from e2e_tes repo.
# Example:
# ./hello_world.sh
# cert-csi test vio --sc <storage class> --chainNumber 2 --chainLength 2
run:
- cert-csi test vio --sc isilon --chainNumber 2 --chainLength 2

- name: Cert CSI # name of custom test to run
# Provide command-line argument to run. Ginkgo will run the command and return output
# The command should be accessible from e2e_tes repo.
# Example:
# ./hello_world.sh
# cert-csi test vio --sc <storage class> --chainNumber 2 --chainLength 2
run:
- cert-csi test vio --sc isilon --chainNumber 2 --chainLength 2
```
Each test has:
Expand All @@ -155,7 +157,11 @@ Each test has:
- `path`: The path to the custom resources yaml file that has the specific configuration you want to test.
- `tags`: Each test can belong to one or more groups of tests, specified by tags. To see a list of currently available tags, run `./run-e2e-test.sh -h`.
- `steps`: Steps to take for the specific scenearios. Please note that all steps above and the ones in this sample file `tests/e2e/testfiles/values.yaml` already have a backend implementation. If you desire to use a different step, see [Develop](#develop) for how to add new E2E Test
- `customTest`: An entrypoint for users to run custom test against their environment. You must have `"Run custom test"` as part of your `steps` above for this custom test to run. This object has the following parameter.
- `customTest`: An array of entrypoints for users to run custom tests against their environment. There are two methods of running custom tests.
- You may have `"Run custom test"` as part of your `steps` above if there is *only one custom test in the array of tests*.
- You may have `"Run [Test Name]"`as part of your `steps` above to *select a custom test from the array by its name*

An object in this array has the following parameters:
- `name`: Name of your custom test
- `run`: A list of command line arguments that will be run by the e2e test.

Expand Down
9 changes: 9 additions & 0 deletions tests/e2e/array-info.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ export PFLEX_ENDPOINT="10.1.1.1"
export PFLEX_MDM="10.0.0.1,10.0.0.2"
export PFLEX_NAS="none"
export PFLEX_AUTH_ENDPOINT="localhost:9401"
# an additional PFlex array is necessary for zoning tests
export PFLEX_ZONING_USER="zoningUsername"
export PFLEX_ZONING_PASS="zoningPassword"
export PFLEX_ZONING_SYSTEMID="zoningSystemID"
export PFLEX_ZONING_ENDPOINT="10.1.1.2"
export PFLEX_ZONING_MDM="10.0.0.3,10.0.0.4"
export PFLEX_ZONING_NAS="none"
export PFLEX_ZONING_POOL="pool1"

# The following are Authorization Proxy Server specific for powerflex:
export PFLEX_POOL="pool1"
export PFLEX_STORAGE="powerflex"
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func TestE2E(t *testing.T) {
}

var _ = BeforeSuite(func() {
tagEnvVars := []string{"NOMODULES", "AUTHORIZATION", "REPLICATION", "OBSERVABILITY", "AUTHORIZATIONPROXYSERVER", "RESILIENCY", "APPLICATIONMOBILITY", "POWERFLEX", "POWERSCALE", "POWERMAX", "POWERSTORE", "UNITY", "SANITY"}
tagEnvVars := []string{"NOMODULES", "AUTHORIZATION", "REPLICATION", "OBSERVABILITY", "AUTHORIZATIONPROXYSERVER", "RESILIENCY", "APPLICATIONMOBILITY", "POWERFLEX", "POWERSCALE", "POWERMAX", "POWERSTORE", "UNITY", "SANITY", "ZONING"}
By("Getting test environment variables")
valuesFile := os.Getenv(valuesFileEnvVar)
Expect(valuesFile).NotTo(BeEmpty(), "Missing environment variable required for tests. E2E_SCENARIOS_FILE must be set.")
Expand Down
8 changes: 4 additions & 4 deletions tests/e2e/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ toolchain go1.23.2

require (
github.com/dell/csm-operator v0.0.0
github.com/onsi/ginkgo/v2 v2.20.2
github.com/onsi/gomega v1.34.2
github.com/onsi/ginkgo/v2 v2.22.0
github.com/onsi/gomega v1.36.0
golang.org/x/mod v0.22.0
k8s.io/api v0.31.3
k8s.io/apimachinery v0.31.3
Expand Down Expand Up @@ -49,7 +49,7 @@ require (
github.com/google/gnostic-models v0.6.9 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
Expand Down Expand Up @@ -98,7 +98,7 @@ require (
golang.org/x/term v0.26.0 // indirect
golang.org/x/text v0.20.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.24.0 // indirect
golang.org/x/tools v0.26.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
google.golang.org/grpc v1.66.2 // indirect
Expand Down
8 changes: 8 additions & 0 deletions tests/e2e/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA=
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
Expand Down Expand Up @@ -120,8 +122,12 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4=
github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag=
github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8=
github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc=
github.com/onsi/gomega v1.36.0 h1:Pb12RlruUtj4XUuPUqeEWc6j5DkVVVA49Uf6YLfC95Y=
github.com/onsi/gomega v1.36.0/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
Expand Down Expand Up @@ -248,6 +254,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
197 changes: 197 additions & 0 deletions tests/e2e/modify_zoning_labels.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# Copyright © 2024 Dell Inc. or its subsidiaries. All Rights Reserved.
#
# 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.

#!/bin/bash

# This script is used as a command line argument in the e2e CustomTest section. It will
# add and remove zone labels for an e2e scenario.
#
# To add a zone label:
# ./modify_zoning_labels.sh add <zone1> <zone2> ...
# To remove a zone label:
# ./modify_zoning_labels.sh remove <zone-key>
# To remove all zone labels:
# ./modify_zoning_labels.sh remove-all-zones
# To validate the zone labels:
# ./modify_zoning_labels.sh validate-zoning

# get all worker node names in the cluster
get_worker_nodes() {
kubectl get nodes -A | grep -v -E 'master|control-plane' | grep -v NAME | awk '{ print $1 }'
}

# add zone label to all worker nodes
add_zone_label() {
local zones=("$@")
local index=0
for node in $(get_worker_nodes); do
local zone=${zones[$index]}
if kubectl label nodes $node $zone; then
echo "Added zone label '$zone' to $node"
else
echo "Failed to add zone label '$zone' to $node"
fi

index=$((index + 1))
# reset the index if we reach the end of the zones array
if [ $index -ge ${#zones[@]} ]; then
index=0
fi
done
}

# remove a specific zone label from worker nodes
remove_zone_label() {
local zone=$1
nodes=$(kubectl get nodes -l $zone -o name)
if [ -z "$nodes" ]; then
echo "No nodes found with zone '$zone'"
return
fi

for node in $(get_worker_nodes); do
if kubectl label nodes $node $zone-; then
echo "Removed label '$zone' from $node"
else
echo "Failed to remove label '$zone' from $node"
fi
done
}

# remove all labels from worker nodes starting with zone
remove_all_zone_labels() {
for node in $(get_worker_nodes); do
labels=$(kubectl get node $node -o jsonpath='{.metadata.labels}' | jq -r 'keys[]')

for label in $labels; do
# this will remove all labels that start with "zone"
if [[ $label == zone* ]]; then
if kubectl label nodes $node $label-; then
echo "Removed label '$label' from $node"
else
echo "Failed to remove label '$label' from $node"
fi
fi
done
done
}

# validation part of script

# read the Kubernetes secret and extract zone information
read_secret() {
secret_name=$1
driverNamespace=$2
secret_data=$(kubectl get secret $secret_name -n $driverNamespace -o jsonpath='{.data.config}')
echo $secret_data | base64 --decode
}

# validating zoning is configured on the cluster
validate_zoning() {
# read the secret and extract zone information
secret_name="test-vxflexos-config"
namespace="vxflexos"
secret_content=$(read_secret $secret_name $namespace)

# parse the secret content to extract zones
local zones=()
while IFS= read -r line; do
if [[ $line =~ name: ]]; then
zone=$(echo "${line##* }" | tr -d '"')
zones+=("$zone")
fi
done <<< "$(echo "$secret_content" | grep -A 1 'zone:' | grep 'name:')"
echo "$secret_content" | grep -A 1 'zone:' | grep 'name:'

echo "Configured zones in secret: ${zones[@]}"

# list all pods in the driver namespace
pods=$(kubectl get pods -n $namespace -o jsonpath='{.items[*].metadata.name}')

# create a map of pods and the nodes they're running on
declare -A pod_node_map
for pod in $pods; do
# check for running pods
status=$(kubectl get pod $pod -n $namespace -o jsonpath='{.status.phase}')
if [ "$status" == "Running" ]; then
# get the node name
node=$(kubectl get pod $pod -n $namespace -o jsonpath='{.spec.nodeName}')
pod_node_map[$pod]=$node
else
echo "Pod $pod is not running. Status: $status"
exit 1
fi
done

# query the nodes to ensure they have zone labels
for node in "${pod_node_map[@]}"; do
echo "Checking node: $node"
getLabel=$(kubectl get node $node -o jsonpath="{.metadata.labels}")
zone_label=$(echo "$getLabel" | jq -r '.["zone.csi-vxflexos.dellemc.com"]')

echo "Node $node zone label: $zone_label"

match_found=false
for zone in "${zones[@]}"; do
echo "Comparing node zone label '$zone_label' with expected zone '$zone'"
if [ "$zone" == "$zone_label" ]; then
match_found=true
echo "Node $node has a matching zone label: $zone_label"
break
fi
done

if [ "$match_found" == false ]; then
echo "Node $node does not have a matching zone label: $zone_label"
exit 1
fi
done
}

if [ "$#" -lt 1 ]; then
echo "Usage: $0 add <zone1> <zone2> ... | remove <label> | remove-all-zones | validate-zoning"
exit 1
fi

action=$1
shift

case $action in
add)
if [ "$#" -lt 1 ]; then
echo "Usage: $0 add <zone1> <zone2> ..."
exit 1
fi
add_zone_label "$@"
;;
remove)
if [ "$#" -ne 1 ]; then
echo "Usage: $0 remove <zone>"
exit 1
fi
zone=$1
remove_zone_label $zone
;;
remove-all-zones)
remove_all_zone_labels
;;
validate-zoning)
validate_zoning
;;
*)
echo "Invalid action: $action"
echo "Usage: $0 add <zone1> <zone2> ... | remove <label> | remove-all-zones | validate-zoning"
exit 1
;;
esac

exit 0
4 changes: 4 additions & 0 deletions tests/e2e/run-e2e-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export REPLICATION=false
export OBSERVABILITY=false
export RESILIENCY=false
export APPLICATIONMOBILITY=false
export ZONING=false

set -o errexit
set -o nounset
Expand Down Expand Up @@ -169,6 +170,7 @@ function usage() {
echo " --pstore use to run e2e powerstore suite"
echo " --unity use to run e2e unity suite"
echo " --pmax use to run e2e powermax suite"
echo " --zoning use to run powerflex zoning tests (requires multiple storage systems)"
echo " --minimal use minimal testfiles scenarios"
echo

Expand Down Expand Up @@ -215,6 +217,8 @@ while getopts ":hv-:" optchar; do
export UNITY=true ;;
pmax)
export POWERMAX=true ;;
zoning)
export ZONING=true ;;
cert-csi)
CERT_CSI="${!OPTIND}"
OPTIND=$((OPTIND + 1))
Expand Down
10 changes: 5 additions & 5 deletions tests/e2e/steps/step_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ type CustomTest struct {

// Scenario -
type Scenario struct {
Scenario string `json:"scenario" yaml:"scenario"`
Paths []string `json:"paths" yaml:"paths"`
Tags []string `json:"tags" yaml:"tags"`
Steps []string `json:"steps" yaml:"steps"`
CustomTest CustomTest `json:"customTest,omitempty" yaml:"customTest"`
Scenario string `json:"scenario" yaml:"scenario"`
Paths []string `json:"paths" yaml:"paths"`
Tags []string `json:"tags" yaml:"tags"`
Steps []string `json:"steps" yaml:"steps"`
CustomTest []CustomTest `json:"customTest,omitempty" yaml:"customTest"`
}

// Resource -
Expand Down
Loading

0 comments on commit b734947

Please sign in to comment.