From 0979f33a22ceeef0d2f31b9909ee83d82ed3c1c9 Mon Sep 17 00:00:00 2001 From: Jackson West Date: Fri, 13 Dec 2024 09:31:35 -0600 Subject: [PATCH] adds exec and logs to join e2e test --- go.mod | 6 ++++ go.sum | 9 ++++++ test/e2e/kubernetes/kubernetes.go | 51 +++++++++++++++++++++++++++++++ test/e2e/suite/nodeadm_test.go | 27 ++++++++++++++++ 4 files changed, 93 insertions(+) diff --git a/go.mod b/go.mod index 84cf3c83..bd32a1cc 100644 --- a/go.mod +++ b/go.mod @@ -32,6 +32,12 @@ require ( sigs.k8s.io/controller-runtime v0.17.0 ) +require ( + github.com/gorilla/websocket v1.5.0 // indirect + github.com/moby/spdystream v0.2.0 // indirect + github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect +) + require ( dario.cat/mergo v1.0.1 // direct github.com/Microsoft/go-winio v0.6.1 // indirect diff --git a/go.sum b/go.sum index b5c2d8a8..18d7114b 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go-v2 v1.32.4 h1:S13INUiTxgrPueTmrm5DZ+MiAo99zYzHEFh1UNkOxNE= @@ -98,6 +100,9 @@ github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 h1:ASJ/LAqdCHOyMYI+dw github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= 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.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -125,6 +130,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -132,6 +139,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= diff --git a/test/e2e/kubernetes/kubernetes.go b/test/e2e/kubernetes/kubernetes.go index 555493bf..6565d917 100644 --- a/test/e2e/kubernetes/kubernetes.go +++ b/test/e2e/kubernetes/kubernetes.go @@ -1,17 +1,23 @@ package kubernetes import ( + "bytes" "context" "fmt" + "io" "time" "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/remotecommand" ) const ( @@ -251,3 +257,48 @@ func EnsureNodeWithIPIsDeleted(ctx context.Context, k8s *kubernetes.Clientset, i } return nil } + +func GetPodLogs(ctx context.Context, k8s *kubernetes.Clientset, name, namespace string) (string, error) { + req := k8s.CoreV1().Pods(namespace).GetLogs(name, &corev1.PodLogOptions{}) + podLogs, err := req.Stream(ctx) + if err != nil { + return "", fmt.Errorf("opening log stream: %w", err) + } + defer podLogs.Close() + + buf := new(bytes.Buffer) + if _, err = io.Copy(buf, podLogs); err != nil { + return "", fmt.Errorf("getting logs from stream: %w", err) + } + + return buf.String(), nil +} + +func ExecPod(ctx context.Context, config *restclient.Config, k8s *kubernetes.Clientset, name, namespace string, cmd ...string) (string, string, error) { + req := k8s.CoreV1().RESTClient().Post().Resource("pods").Name(name).Namespace(namespace).SubResource("exec") + req.VersionedParams( + &v1.PodExecOptions{ + Command: cmd, + Stdin: false, + Stdout: true, + Stderr: true, + TTY: true, + }, + scheme.ParameterCodec, + ) + exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL()) + if err != nil { + return "", "", err + } + var stdout, stderr bytes.Buffer + err = exec.StreamWithContext(ctx, remotecommand.StreamOptions{ + Stdin: nil, + Stdout: &stdout, + Stderr: &stderr, + }) + if err != nil { + return "", "", err + } + + return stdout.String(), stderr.String(), nil +} diff --git a/test/e2e/suite/nodeadm_test.go b/test/e2e/suite/nodeadm_test.go index 5d9c3127..9b981b13 100644 --- a/test/e2e/suite/nodeadm_test.go +++ b/test/e2e/suite/nodeadm_test.go @@ -8,6 +8,7 @@ import ( "flag" "fmt" "os" + "strings" "testing" "time" @@ -316,6 +317,7 @@ var _ = Describe("Hybrid Nodes", func() { }) joinNodeTest := joinNodeTest{ + clientConfig: test.k8sClientConfig, k8s: test.k8sClient, nodeIPAddress: instance.IP, logger: test.logger, @@ -355,6 +357,7 @@ var _ = Describe("Hybrid Nodes", func() { }) type joinNodeTest struct { + clientConfig *restclient.Config k8s *clientgo.Clientset nodeIPAddress string logger logr.Logger @@ -384,6 +387,29 @@ func (t joinNodeTest) Run(ctx context.Context) error { } t.logger.Info(fmt.Sprintf("Pod %s created and running on node %s", podName, nodeName)) + t.logger.Info("Exec-ing nginx -version", "pod", podName) + stdout, stderr, err := kubernetes.ExecPod(ctx, t.clientConfig, t.k8s, podName, podNamespace, "/sbin/nginx", "-version") + if err != nil { + return err + } + if !strings.Contains(stdout, "nginx") { + return fmt.Errorf("pod exec stdout does not contain expected value %s: %s", stdout, "nginx") + } + if stderr != "" { + return fmt.Errorf("pod exec stderr should be empty %s", stderr) + } + t.logger.Info("Successfully exec'd nginx -version", "pod", podName) + + t.logger.Info("Checking logs for nginx output", "pod", podName) + logs, err := kubernetes.GetPodLogs(ctx, t.k8s, podName, podNamespace) + if err != nil { + return err + } + if !strings.Contains(logs, "nginx") { + return fmt.Errorf("pod log does not contain expected value %s: %s", logs, "nginx") + } + t.logger.Info("Successfully validated log output", "pod", podName) + t.logger.Info("Deleting test pod", "pod", podName) if err = kubernetes.DeletePod(ctx, t.k8s, podName, podNamespace); err != nil { return err @@ -495,6 +521,7 @@ func buildPeeredVPCTestForSuite(ctx context.Context, suite *suiteConfiguration) if err != nil { return nil, err } + test.k8sClientConfig = clientConfig test.k8sClient, err = clientgo.NewForConfig(clientConfig) if err != nil { return nil, err