Skip to content

Commit

Permalink
Update e2e test case (#888)
Browse files Browse the repository at this point in the history
* Use CRD ClientSet to get CRD resource
* Improve some test cases
* Update the test-e2e script
* Remove the `ippool` parameter
* Add a `debug` parameter to improve the test log output
---------

Signed-off-by: Wenqi Qiu <[email protected]>
  • Loading branch information
wenqiq authored Nov 15, 2024
1 parent 3ce44b7 commit 828b8d8
Show file tree
Hide file tree
Showing 6 changed files with 365 additions and 383 deletions.
2 changes: 1 addition & 1 deletion hack/test-e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export GOROOT=/usr/local/go
export PATH=$GOROOT/bin:$PATH
go version
go env
go clean -cache -modcache -testcache

# if manual trigger, use the default email and author
if [ -z ${ghprbActualCommitAuthorEmail+x} ]; then
Expand Down Expand Up @@ -57,7 +58,6 @@ kubectl exec $pod_name -c nsx-ncp -n vmware-system-nsx -- cat /var/run/secrets/k
kubectl exec $pod_name -c nsx-ncp -n vmware-system-nsx -- cat /etc/nsx-ujo/vc/username > /etc/nsx-ujo/vc/username
kubectl exec $pod_name -c nsx-ncp -n vmware-system-nsx -- cat /etc/nsx-ujo/vc/password > /etc/nsx-ujo/vc/password

cp -r /root/test $NSX_OPERATOR_DIR/
# Use the -run parameter to run only specific test cases within certain modules.
# -run '.*Subnet.*|.*SubnetSet.*|.*SecurityPolicy.*|.*NetworkInfo.*'
e2e=true go test -v ./test/e2e -coverpkg=./pkg/... -remote.kubeconfig /root/.kube/config -operator-cfg-path /etc/ncp.ini -test.timeout 15m -coverprofile cover-e2e.out
144 changes: 1 addition & 143 deletions test/e2e/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ type TestOptions struct {
logsExportDir string
operatorConfigPath string
logsExportOnSuccess bool
withIPPool bool
debugLog bool
}

var testOptions TestOptions
Expand Down Expand Up @@ -304,148 +304,6 @@ func (data *TestData) deleteNamespace(namespace string, timeout time.Duration) e

type PodCondition func(*corev1.Pod) (bool, error)

// waitForSecurityPolicyReady polls the K8s apiServer until the specified CR is in the "True" state (or until
// the provided timeout expires).
func (data *TestData) waitForCRReadyOrDeleted(timeout time.Duration, cr string, namespace string, name string, status Status) error {
err := wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, timeout, false, func(ctx context.Context) (bool, error) {
cmd := fmt.Sprintf("kubectl get %s %s -n %s -o jsonpath='{.status.conditions[?(@.type==\"Ready\")].status}'", cr, name, namespace)
rc, stdout, stderr, err := RunCommandOnNode(clusterInfo.masterNodeName, cmd)
log.Printf("Command: %s\n, result: %d, stdout: %s, stderr:%s, error: %+v\n", cmd, rc, stdout, stderr, err)
if err != nil || rc != 0 {
if status == Deleted {
return true, nil
}
return false, fmt.Errorf("error when running the following command `%s` on master Node: %v, %s", cmd, err, stdout)
} else {
if status == Ready {
if stdout == "True" {
return true, nil
}
return false, nil
}
return false, nil
}
})
if err != nil {
return err
}
return nil
}

func (data *TestData) getCRPropertiesByJson(timeout time.Duration, crType, crName, namespace, key string) (string, error) {
value := ""
err := wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, timeout, false, func(ctx context.Context) (bool, error) {
cmd := ""
// for cluster scope resource, namespace is empty
if namespace == "" {
cmd = fmt.Sprintf("kubectl get %s %s -o json | jq '%s'", crType, crName, key)
} else {
cmd = fmt.Sprintf("kubectl get %s %s -n %s -o json | jq '%s'", crType, crName, namespace, key)
}
log.Printf("%s", cmd)
rc, stdout, _, err := RunCommandOnNode(clusterInfo.masterNodeName, cmd)
if err != nil || rc != 0 {
return false, fmt.Errorf("error when running the following command `%s` on master Node: %v, %s", cmd, err, stdout)
} else {
// check if 'null' in stdout
if strings.Contains(stdout, "null") {
return false, nil
}
value = stdout
return true, nil
}
})
if err != nil {
return value, err
}
return value, nil
}

// For CRs that we do not know the name, return the CR list for upper logic to identify
func (data *TestData) getCRResources(timeout time.Duration, crtype, namespace string) (map[string]string, error) {
crs := map[string]string{}
err := wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, timeout, false, func(ctx context.Context) (bool, error) {
cmd := ""
if namespace == "" { // for cluster scope resources
cmd = fmt.Sprintf("kubectl get %s", crtype)
} else if crtype == "namespaces" {
cmd = fmt.Sprintf("kubectl get %s %s", crtype, namespace)
} else {
cmd = fmt.Sprintf("kubectl get %s -n %s", crtype, namespace)
}
log.Printf("%s", cmd)
rc, stdout, _, err := RunCommandOnNode(clusterInfo.masterNodeName, cmd)
if err != nil || rc != 0 {
return false, fmt.Errorf("error when running the following command `%s` on master Node: %v, %s", cmd, err, stdout)
} else {
crs_raw := strings.Split(stdout, "\n")
// for each resource, get json structure as value
for i, c := range crs_raw {
if i == 0 {
// first line is table header
continue
}
r := regexp.MustCompile("[^\\s]+")
parts := r.FindAllString(c, -1)
if len(parts) < 1 { // to avoid empty lines
continue
}
uid_cmd := ""
if namespace == "" || crtype == "namespaces" {
uid_cmd = fmt.Sprintf("kubectl get %s %s -o yaml | grep uid", crtype, parts[0])
} else {
uid_cmd = fmt.Sprintf("kubectl get %s %s -n %s -o yaml | grep uid", crtype, parts[0], namespace)
}
log.Printf("trying to get uid for cr: %s", uid_cmd)
rc, stdout, _, err := RunCommandOnNode(clusterInfo.masterNodeName, uid_cmd)
if err != nil || rc != 0 {
return false, fmt.Errorf("error when running the following command `%s` on master Node: %v, %s", uid_cmd, err, stdout)
}
uid := strings.Split(stdout, ":")[1]
crs[parts[0]] = uid
}
return true, nil
}
})
if err != nil {
return crs, err
}
return crs, nil
}

// Return a singe CR via CR name
func (data *TestData) getCRResource(timeout time.Duration, crtype, crname, namespace string) (string, error) {
ret := ""
err := wait.PollUntilContextTimeout(context.TODO(), 1*time.Second, timeout, false, func(ctx context.Context) (bool, error) {
// If namespace is empty, then this is a cluster scope resource.
uid_cmd := ""
if namespace == "" {
uid_cmd = fmt.Sprintf("kubectl get %s %s -o yaml | grep uid", crtype, crname)
} else if crtype == "namespaces" {
uid_cmd = fmt.Sprintf("kubectl get %s %s -o yaml | grep uid", crtype, namespace)
} else {
uid_cmd = fmt.Sprintf("kubectl get %s %s -n %s -o yaml | grep uid", crtype, crname, namespace)
}
log.Printf("%s", uid_cmd)
rc, stdout, _, err := RunCommandOnNode(clusterInfo.masterNodeName, uid_cmd)
if err != nil || rc != 0 {
return false, fmt.Errorf("error when running the following command `%s` on master Node: %v, %s", uid_cmd, err, stdout)
} else {
parts := strings.Split(stdout, ":")
if len(parts) < 2 {
return false, nil
}
uid := parts[1]
ret = uid
}
return true, nil
})
if err != nil {
return "", err
}
return ret, nil
}

// deploymentWaitForNames polls the K8s apiServer once the specific pods are created, no matter they are running or not.
func (data *TestData) deploymentWaitForNames(timeout time.Duration, namespace, deployment string) ([]string, error) {
var podNames []string
Expand Down
9 changes: 7 additions & 2 deletions test/e2e/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@ func testMain(m *testing.M) int {
flag.StringVar(&testOptions.logsExportDir, "logs-export-dir", "", "Export directory for test logs")
flag.StringVar(&testOptions.operatorConfigPath, "operator-cfg-path", "/etc/nsx-ujo/ncp.ini", "config file for operator")
flag.BoolVar(&testOptions.logsExportOnSuccess, "logs-export-on-success", false, "Export logs even when a test is successful")
flag.BoolVar(&testOptions.withIPPool, "ippool", false, "Run tests include IPPool tests")
flag.BoolVar(&testOptions.debugLog, "debug", false, "")
flag.Parse()

logf.SetLogger(logger.ZapLogger(true, 2))
if testOptions.debugLog {
logf.SetLogger(logger.ZapLogger(true, 2))
} else {
logf.SetLogger(logger.ZapLogger(false, 0))

}

if err := initProvider(); err != nil {
log.Fatalf("Error when initializing provider: %v", err)
Expand Down
Loading

0 comments on commit 828b8d8

Please sign in to comment.