Skip to content

Commit

Permalink
Improve the readability of post-installation test results
Browse files Browse the repository at this point in the history
* Test results will be displayed in green, red, and yellow to indicate
  success, failure, and skipped, respectively.
* Show the total number of success, failure, and skipped tests in the
  end.
* Return error if any test fails. Otherwise, it would be hard for
  automation tools to detect whether the check succeeds or not.

Signed-off-by: Quan Tian <[email protected]>
  • Loading branch information
tnqn committed May 6, 2024
1 parent f0d0a6b commit 58c26a6
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 17 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ require (
github.com/containernetworking/plugins v1.1.1
github.com/coreos/go-iptables v0.7.0
github.com/davecgh/go-spew v1.1.1
github.com/fatih/color v1.15.0
github.com/fsnotify/fsnotify v1.7.0
github.com/gammazero/deque v0.1.2
github.com/go-logr/logr v1.4.1
Expand All @@ -41,6 +42,7 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
github.com/onsi/ginkgo/v2 v2.17.2
github.com/onsi/gomega v1.33.1
github.com/pkg/errors v0.9.1
github.com/pkg/sftp v1.13.6
github.com/prometheus/client_golang v1.18.0
github.com/prometheus/common v0.47.0
Expand Down Expand Up @@ -126,7 +128,6 @@ require (
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fvbommel/sortorder v1.1.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
Expand Down Expand Up @@ -186,7 +187,6 @@ require (
github.com/pion/logging v0.2.2 // indirect
github.com/pion/transport/v2 v2.0.0 // indirect
github.com/pion/udp v0.1.4 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
Expand Down
34 changes: 29 additions & 5 deletions pkg/antctl/raw/check/installation/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"os"
"time"

"github.com/fatih/color"
"github.com/spf13/cobra"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -69,7 +70,9 @@ const (
)

type Test interface {
Run(ctx context.Context, testContext *testContext) error
// Run executes the test using the provided testContext.
// It returns a non-nil error when the test doesn't succeed and a bool indicating whether the test is skipped or not.
Run(ctx context.Context, testContext *testContext) (error, bool)
}

var testsRegistry = make(map[string]Test)
Expand Down Expand Up @@ -99,16 +102,25 @@ func Run(o *options) error {
if err := testContext.setup(ctx); err != nil {
return err
}
var numSuccess, numFailure, numSkipped int
for name, test := range testsRegistry {
testContext.Header("Running test: %s", name)
if err := test.Run(ctx, testContext); err != nil {
testContext.Header("Test %s failed: %s", name, err)
if err, skipped := test.Run(ctx, testContext); skipped {
testContext.Warning("Test %s was skipped: %v", name, err)
numSkipped++
} else if err != nil {
testContext.Fail("Test %s failed: %v", name, err)
numFailure++
} else {
testContext.Header("Test %s passed", name)
testContext.Success("Test %s passed", name)
numSuccess++
}
}
testContext.Log("Test finished")
testContext.Log("Test finished: %v tests succeeded, %v tests failed, %v tests were skipped", numSuccess, numFailure, numSkipped)
testContext.teardown(ctx)
if numFailure > 0 {
return fmt.Errorf("%v/%v tests failed", numFailure, len(testsRegistry))
}
return nil
}

Expand Down Expand Up @@ -397,6 +409,18 @@ func (t *testContext) Log(format string, a ...interface{}) {
fmt.Fprintf(os.Stdout, fmt.Sprintf("[%s] ", t.clusterName)+format+"\n", a...)
}

func (t *testContext) Success(format string, a ...interface{}) {
fmt.Fprintf(os.Stdout, fmt.Sprintf("[%s] ", t.clusterName)+color.GreenString(format, a...)+"\n")
}

func (t *testContext) Fail(format string, a ...interface{}) {
fmt.Fprintf(os.Stdout, fmt.Sprintf("[%s] ", t.clusterName)+color.RedString(format, a...)+"\n")
}

func (t *testContext) Warning(format string, a ...interface{}) {
fmt.Fprintf(os.Stdout, fmt.Sprintf("[%s] ", t.clusterName)+color.YellowString(format, a...)+"\n")
}

func (t *testContext) Header(format string, a ...interface{}) {
t.Log("-------------------------------------------------------------------------------------------")
t.Log(format, a...)
Expand Down
6 changes: 3 additions & 3 deletions pkg/antctl/raw/check/installation/test_podtointernet.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ func init() {
RegisterTest("pod-to-internet-connectivity", &PodToInternetConnectivityTest{})
}

func (t *PodToInternetConnectivityTest) Run(ctx context.Context, testContext *testContext) error {
func (t *PodToInternetConnectivityTest) Run(ctx context.Context, testContext *testContext) (error, bool) {
for _, clientPod := range testContext.clientPods {
srcPod := testContext.namespace + "/" + clientPod.Name
testContext.Log("Validating connectivity from Pod %s to the world (google.com)...", srcPod)
_, _, err := check.ExecInPod(ctx, testContext.client, testContext.config, testContext.namespace, clientPod.Name, clientDeploymentName, agnhostConnectCommand("google.com", "80"))
if err != nil {
return fmt.Errorf("Pod %s was not able to connect to google.com: %w", srcPod, err)
return fmt.Errorf("Pod %s was not able to connect to google.com: %w", srcPod, err), false
}
testContext.Log("Pod %s was able to connect to google.com", srcPod)
}
return nil
return nil, false
}
8 changes: 4 additions & 4 deletions pkg/antctl/raw/check/installation/test_podtopodinternode.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ func init() {
RegisterTest("pod-to-pod-internode-connectivity", &PodToPodInterNodeConnectivityTest{})
}

func (t *PodToPodInterNodeConnectivityTest) Run(ctx context.Context, testContext *testContext) error {
func (t *PodToPodInterNodeConnectivityTest) Run(ctx context.Context, testContext *testContext) (error, bool) {
if testContext.echoOtherNodePod == nil {
return fmt.Errorf("Skipping Inter-Node test because multiple Nodes are not available")
return fmt.Errorf("Inter-Node test requires multiple Nodes"), true
}
for _, clientPod := range testContext.clientPods {
srcPod := testContext.namespace + "/" + clientPod.Name
Expand All @@ -39,10 +39,10 @@ func (t *PodToPodInterNodeConnectivityTest) Run(ctx context.Context, testContext
testContext.Log("Validating from Pod %s to Pod %s at IP %s...", srcPod, dstPod, echoIP)
_, _, err := check.ExecInPod(ctx, testContext.client, testContext.config, testContext.namespace, clientPod.Name, "", agnhostConnectCommand(echoIP, "80"))
if err != nil {
return fmt.Errorf("client Pod %s was not able to communicate with echo Pod %s (%s): %w", clientPod.Name, testContext.echoOtherNodePod.Name, echoIP, err)
return fmt.Errorf("client Pod %s was not able to communicate with echo Pod %s (%s): %w", clientPod.Name, testContext.echoOtherNodePod.Name, echoIP, err), false
}
testContext.Log("client Pod %s was able to communicate with echo Pod %s (%s)", clientPod.Name, testContext.echoOtherNodePod.Name, echoIP)
}
}
return nil
return nil, false
}
6 changes: 3 additions & 3 deletions pkg/antctl/raw/check/installation/test_podtopodintranode.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func init() {
RegisterTest("pod-to-pod-intranode-connectivity", &PodToPodIntraNodeConnectivityTest{})
}

func (t *PodToPodIntraNodeConnectivityTest) Run(ctx context.Context, testContext *testContext) error {
func (t *PodToPodIntraNodeConnectivityTest) Run(ctx context.Context, testContext *testContext) (error, bool) {
for _, clientPod := range testContext.clientPods {
srcPod := testContext.namespace + "/" + clientPod.Name
dstPod := testContext.namespace + "/" + testContext.echoSameNodePod.Name
Expand All @@ -36,10 +36,10 @@ func (t *PodToPodIntraNodeConnectivityTest) Run(ctx context.Context, testContext
testContext.Log("Validating from Pod %s to Pod %s at IP %s...", srcPod, dstPod, echoIP)
_, _, err := check.ExecInPod(ctx, testContext.client, testContext.config, testContext.namespace, clientPod.Name, "", agnhostConnectCommand(echoIP, "80"))
if err != nil {
return fmt.Errorf("client Pod %s was not able to communicate with echo Pod %s (%s): %w", clientPod.Name, testContext.echoSameNodePod.Name, echoIP, err)
return fmt.Errorf("client Pod %s was not able to communicate with echo Pod %s (%s): %w", clientPod.Name, testContext.echoSameNodePod.Name, echoIP, err), false
}
testContext.Log("client Pod %s was able to communicate with echo Pod %s (%s)", clientPod.Name, testContext.echoSameNodePod.Name, echoIP)
}
}
return nil
return nil, false
}

0 comments on commit 58c26a6

Please sign in to comment.