Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

connectivity client upgrade e2e #633

Merged
merged 2 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 60 additions & 17 deletions tests/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@ const (
)

var (
testResources []step.Resource
tagsSpecified []string
stepRunner *step.Runner
beautify string
testResources []step.Resource
testResourcesApex []step.ResourceApex
tagsSpecified []string
stepRunner *step.Runner
beautify string
testCsm bool
testApex bool
)

func Contains(slice []string, str string) bool {
Expand Down Expand Up @@ -89,12 +92,28 @@ var _ = BeforeSuite(func() {
}

By(fmt.Sprint(tagsSpecified))

By("Reading values file")
res, err := step.GetTestResources(valuesFile)
if err != nil {
framework.Failf("Failed to read values file: %v", err)
}

testResources = res
if strings.Contains(testResources[0].CustomResource[0].Kind, "ContainerStorageModule") {
testCsm = true
}

By("Reading apex values file")
resApex, err := step.GetTestResourcesApex(valuesFile)
if err != nil {
framework.Failf("Failed to read apex values file: %v", err)
}

testResourcesApex = resApex
if strings.Contains(testResourcesApex[0].CustomResourceApex[0].Kind, "ApexConnectivityClient") {
testApex = true
}

By("Getting a k8s client")
ctrlClient, err := client.New(config.GetConfigOrDie(), client.Options{})
Expand All @@ -112,26 +131,50 @@ var _ = BeforeSuite(func() {
step.StepRunnerInit(stepRunner, ctrlClient, clientSet)

beautify = " "

})

var _ = Describe("[run-e2e-test] E2E Testing", func() {

It("Running all test Given Test Scenarios", func() {
for _, test := range testResources {
By(fmt.Sprintf("Starting: %s ", test.Scenario.Scenario))
if ContainsTag(test.Scenario.Tags, tagsSpecified) == false {
By(fmt.Sprintf("Not tagged for this test run, skipping"))
By(fmt.Sprintf("Ending: %s\n", test.Scenario.Scenario))
continue
if testApex {
for _, test := range testResourcesApex {
By(fmt.Sprintf("Starting: %s ", test.ScenarioApex.Scenario))
if ContainsTag(test.ScenarioApex.Tags, tagsSpecified) == false {
By(fmt.Sprintf("Not tagged for this test run, skipping"))
By(fmt.Sprintf("Ending: %s\n", test.ScenarioApex.Scenario))
continue
}

for _, stepName := range test.ScenarioApex.Steps {
By(fmt.Sprintf("%s Executing %s", beautify, stepName))
Eventually(func() error {
return stepRunner.RunStepClient(stepName, test)
}, timeout, interval).Should(BeNil())
}
By(fmt.Sprintf("Ending: %s\n", test.ScenarioApex.Scenario))
time.Sleep(5 * time.Second)
}

for _, stepName := range test.Scenario.Steps {
By(fmt.Sprintf("%s Executing %s", beautify, stepName))
Eventually(func() error {
return stepRunner.RunStep(stepName, test)
}, timeout, interval).Should(BeNil())
}
if testCsm {
for _, test := range testResources {
By(fmt.Sprintf("Starting: %s ", test.Scenario.Scenario))
if ContainsTag(test.Scenario.Tags, tagsSpecified) == false {
By(fmt.Sprintf("Not tagged for this test run, skipping"))
By(fmt.Sprintf("Ending: %s\n", test.Scenario.Scenario))
continue
}

for _, stepName := range test.Scenario.Steps {
By(fmt.Sprintf("%s Executing %s", beautify, stepName))
Eventually(func() error {
return stepRunner.RunStep(stepName, test)
}, timeout, interval).Should(BeNil())
}
By(fmt.Sprintf("Ending: %s\n", test.Scenario.Scenario))
time.Sleep(5 * time.Second)
}
By(fmt.Sprintf("Ending: %s\n", test.Scenario.Scenario))
time.Sleep(5 * time.Second)
}
})
})
3 changes: 2 additions & 1 deletion tests/e2e/run-e2e-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# Set environment variables and options
###############################################################################
export E2E_SCENARIOS_FILE=testfiles/scenarios.yaml
#export E2E_SCENARIOS_FILE=testfiles/connectivity-values.yaml
export ARRAY_INFO_FILE=array-info.sh
export GO111MODULE=on
export ACK_GINKGO_RC=true
Expand Down Expand Up @@ -254,5 +255,5 @@ if [ -v APPLICATIONMOBILITY ]; then
checkForDellctl
fi
checkForGinkgo
runTests
#runTests

6 changes: 6 additions & 0 deletions tests/e2e/steps/step_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ type Resource struct {
CustomResource []csmv1.ContainerStorageModule
}

// ResourceApex -
type ResourceApex struct {
ScenarioApex Scenario
CustomResourceApex []csmv1.ApexConnectivityClient
}

// Step -
type Step struct {
ctrlClient client.Client
Expand Down
146 changes: 137 additions & 9 deletions tests/e2e/steps/steps_def.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,43 @@ func GetTestResources(valuesFilePath string) ([]Resource, error) {
return resources, nil
}

// GetTestResourcesApex -- parse values file
func GetTestResourcesApex(valuesFilePath string) ([]ResourceApex, error) {
b, err := os.ReadFile(valuesFilePath)
if err != nil {
return nil, fmt.Errorf("failed to read values file: %v", err)
}

scenarios := []Scenario{}
err = yaml.Unmarshal(b, &scenarios)
if err != nil {
return nil, fmt.Errorf("failed to read unmarshal values file: %v", err)
}

resources := []ResourceApex{}
for _, scene := range scenarios {
customResources := []csmv1.ApexConnectivityClient{}
for _, path := range scene.Paths {
b, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed to read testdata: %v", err)
}
customResource := csmv1.ApexConnectivityClient{}
err = yaml.Unmarshal(b, &customResource)
if err != nil {
return nil, fmt.Errorf("failed to read unmarshal CSM custom resource: %v", err)
}
customResources = append(customResources, customResource)
}
resources = append(resources, ResourceApex{
ScenarioApex: scene,
CustomResourceApex: customResources,
})
}

return resources, nil
}

func (step *Step) applyCustomResource(res Resource, crNumStr string) error {
crNum, _ := strconv.Atoi(crNumStr)
cr := res.CustomResource[crNum-1]
Expand Down Expand Up @@ -1300,10 +1337,63 @@ func (step *Step) configureAMInstall(res Resource, templateFile string) error {
}

// Steps for Connectivity Client
func (step *Step) validateClientTestEnvironment(_ ResourceApex) error {
if os.Getenv("OPERATOR_NAMESPACE") != "" {
operatorNamespace = os.Getenv("OPERATOR_NAMESPACE")
}

pods, err := fpod.GetPodsInNamespace(context.TODO(), step.clientSet, operatorNamespace, map[string]string{})
if err != nil {
return err
}
if len(pods) == 0 {
return fmt.Errorf("no pod was found")
}

func (step *Step) validateConnectivityClientInstalled(res Resource, crNumStr string) error {
notReadyMessage := ""
allReady := true
for _, pod := range pods {
if pod.Status.Phase != corev1.PodRunning {
allReady = false
notReadyMessage += fmt.Sprintf("\nThe pod(%s) is %s", pod.Name, pod.Status.Phase)
}
}

if !allReady {
return fmt.Errorf(notReadyMessage)
}

return nil
}

func (step *Step) applyClientCustomResource(res ResourceApex, crNumStr string, secretNumStr string) error {
crNum, _ := strconv.Atoi(crNumStr)
cr := res.CustomResource[crNum-1]
cr := res.CustomResourceApex[crNum-1]
crBuff, err := os.ReadFile(res.ScenarioApex.Paths[crNum-1])
if err != nil {
return fmt.Errorf("failed to read connecivity client testdata: %v", err)
}

scrNum, _ := strconv.Atoi(secretNumStr)
scr := res.CustomResourceApex[scrNum-1]
scrBuff, err := os.ReadFile(res.ScenarioApex.Paths[scrNum-1])
if err != nil {
return fmt.Errorf("failed to read secret testdata: %v", err)
}

if _, err := kubectl.RunKubectlInput(cr.Namespace, string(crBuff), "apply", "--validate=true", "-f", "-"); err != nil {
return fmt.Errorf("failed to apply connecivity client CR %s in namespace %s: %v", cr.Name, cr.Namespace, err)
}
if _, err := kubectl.RunKubectlInput(scr.Namespace, string(scrBuff), "apply", "--validate=true", "-f", "-"); err != nil {
return fmt.Errorf("failed to apply secret CR %s in namespace %s: %v", scr.Name, scr.Namespace, err)
}
return nil
}

func (step *Step) validateConnectivityClientInstalled(res ResourceApex, crNumStr string) error {
crNum, _ := strconv.Atoi(crNumStr)
cr := res.CustomResourceApex[crNum-1]
time.Sleep(60 * time.Second)
found := new(csmv1.ApexConnectivityClient)

if err := step.ctrlClient.Get(context.TODO(), client.ObjectKey{
Expand All @@ -1313,12 +1403,34 @@ func (step *Step) validateConnectivityClientInstalled(res Resource, crNumStr str
return err
}

return checkAllRunningPods(context.TODO(), res.CustomResource[crNum-1].Namespace, step.clientSet)
return checkAllRunningPods(context.TODO(), res.CustomResourceApex[crNum-1].Namespace, step.clientSet)
}

func (step *Step) validateConnectivityClientNotInstalled(res Resource, crNumStr string) error {
func (step *Step) upgradeCustomResourceClient(res ResourceApex, oldCrNumStr string, newCrNumStr string) error {
oldCrNum, _ := strconv.Atoi(oldCrNumStr)
oldCr := res.CustomResourceApex[oldCrNum-1]

newCrNum, _ := strconv.Atoi(newCrNumStr)
newCr := res.CustomResourceApex[newCrNum-1]

found := new(csmv1.ApexConnectivityClient)
if err := step.ctrlClient.Get(context.TODO(), client.ObjectKey{
Namespace: oldCr.Namespace,
Name: oldCr.Name,
}, found); err != nil {
fmt.Printf("Failed to get newCr.Name--> %v", err)
return err
}

// Update old CR with the spec of new CR
found.Spec = newCr.Spec
return step.ctrlClient.Update(context.TODO(), found)
}

func (step *Step) validateConnectivityClientNotInstalled(res ResourceApex, crNumStr string) error {
crNum, _ := strconv.Atoi(crNumStr)
cr := res.CustomResource[crNum-1]
cr := res.CustomResourceApex[crNum-1]
time.Sleep(20 * time.Second)
found := new(csmv1.ApexConnectivityClient)
if err := step.ctrlClient.Get(context.TODO(), client.ObjectKey{
Namespace: cr.Namespace,
Expand All @@ -1327,13 +1439,13 @@ func (step *Step) validateConnectivityClientNotInstalled(res Resource, crNumStr
return fmt.Errorf("Found traces of client installation in namespace %s: %v", cr.Namespace, found)
}

return checkNoRunningPods(context.TODO(), res.CustomResource[crNum-1].Namespace, step.clientSet)
return checkNoRunningPods(context.TODO(), res.CustomResourceApex[crNum-1].Namespace, step.clientSet)
}

// uninstallConnectivityClient - uninstall the client
func (step *Step) uninstallConnectivityClient(res Resource, crNumStr string) error {
func (step *Step) uninstallConnectivityClient(res ResourceApex, crNumStr string) error {
crNum, _ := strconv.Atoi(crNumStr)
cr := res.CustomResource[crNum-1]
cr := res.CustomResourceApex[crNum-1]

found := new(csmv1.ApexConnectivityClient)
err := step.ctrlClient.Get(context.TODO(), client.ObjectKey{
Expand All @@ -1348,7 +1460,7 @@ func (step *Step) uninstallConnectivityClient(res Resource, crNumStr string) err
return err
}

crBuff, err := os.ReadFile(res.Scenario.Paths[crNum-1])
crBuff, err := os.ReadFile(res.ScenarioApex.Paths[crNum-1])
if err != nil {
return fmt.Errorf("failed to read testdata: %v", err)
}
Expand All @@ -1360,6 +1472,22 @@ func (step *Step) uninstallConnectivityClient(res Resource, crNumStr string) err
return nil
}

func (step *Step) uninstallConnectivityClientSecret(res ResourceApex, scrNumStr string) error {
crNum, _ := strconv.Atoi(scrNumStr)
cr := res.CustomResourceApex[crNum-1]

crBuff, err := os.ReadFile(res.ScenarioApex.Paths[crNum-1])
if err != nil {
return fmt.Errorf("failed to read secret testdata: %v", err)
}

if _, err := kubectl.RunKubectlInput(cr.Namespace, string(crBuff), "delete", "--wait=true", "--timeout=30s", "-f", "-"); err != nil {
return fmt.Errorf("failed to delete secret CR %s in namespace %s: %v", cr.Name, cr.Namespace, err)
}

return nil
}

func (step *Step) validateApplicationMobilityNotInstalled(cr csmv1.ContainerStorageModule) error {
fakeReconcile := utils.FakeReconcileCSM{
Client: step.ctrlClient,
Expand Down
35 changes: 34 additions & 1 deletion tests/e2e/steps/steps_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,13 @@ func StepRunnerInit(runner *Runner, ctrlClient client.Client, clientSet *kuberne
runner.addStep(`^Set up application mobility CR \[([^"]*)\]$`, step.configureAMInstall)

// Connectivity Client steps
runner.addStep(`^Install connectivity client from CR \[(\d+)\]$`, step.applyCustomResource)
runner.addStep(`^Given an client environment with k8s or openshift, and CSM operator installed$`, step.validateClientTestEnvironment)
runner.addStep(`^Install connectivity client from CR \[(\d+)\] and create secret \[(\d+)\]$`, step.applyClientCustomResource)
runner.addStep(`^Validate connectivity client from CR \[(\d+)\] is installed$`, step.validateConnectivityClientInstalled)
runner.addStep(`^Validate connectivity client from CR \[(\d+)\] is not installed$`, step.validateConnectivityClientNotInstalled)
runner.addStep(`^Uninstall connectivity client from CR \[(\d+)\]`, step.uninstallConnectivityClient)
runner.addStep(`^Upgrade client from custom resource \[(\d+)\] to \[(\d+)\]$`, step.upgradeCustomResourceClient)
runner.addStep(`^Uninstall connectivity client secret from CR \[(\d+)\]`, step.uninstallConnectivityClientSecret)
runner.addStep(`^Install Authorization CRDs \[(\d+)\]$`, step.createCustomResourceDefinition)
runner.addStep(`^Validate \[([^"]*)\] CRD for Authorization is installed$`, step.validateCustomResourceDefinition)
runner.addStep(`^Delete Authorization CRDs \[(\d+)\]$`, step.deleteCustomResourceDefinition)
Expand Down Expand Up @@ -144,3 +147,33 @@ func (runner *Runner) RunStep(stepName string, res Resource) error {

return fmt.Errorf("no method for step: %s", stepName)
}

// RunStepClient - runs a step
func (runner *Runner) RunStepClient(stepName string, res ResourceApex) error {
for _, stepDef := range runner.Definitions {
if stepDef.Expr.MatchString(stepName) {
var values []reflect.Value
groups := stepDef.Expr.FindStringSubmatch(stepName)

typ := stepDef.Handler.Type()
numArgs := typ.NumIn()
if numArgs > len(groups) {
return fmt.Errorf("expected handler method to take %d but got: %d", numArgs, len(groups))
}

values = append(values, reflect.ValueOf(res))
for i := 1; i < len(groups); i++ {
values = append(values, reflect.ValueOf(groups[i]))
}

res := stepDef.Handler.Call(values)
if err, ok := res[0].Interface().(error); ok {
fmt.Printf("\nerr: %+v\n", err)
return err
}
return nil
}
}

return fmt.Errorf("no method for step: %s", stepName)
}
Loading
Loading