mirror of
https://github.com/replicatedhq/troubleshoot.git
synced 2026-02-14 10:19:54 +00:00
feat: goldpinger collector and analyser (#1398)
* feat: goldpinger analyser Analyser to generate a report from goldpinger results * Add goldpinger testdata * Goldpinger collector * Improvements after running tests * More minor updates after further testing * Better error message if a container fails to start * A few more updates * Add goldpinger e2e test * Update schemas * Clean up help installs in e2e tests * Add resource limits to goldpinger pods * Some minor improvements * Some more changes noted when writing docs * Update schemas * A few more updates when testing with kURL * Log goldpinger tests * Tests before exit code
This commit is contained in:
@@ -42,7 +42,7 @@ func TestDeploymentPod(t *testing.T) {
|
||||
tarPath := fmt.Sprintf("%s.tar.gz", supportBundleName)
|
||||
targetFile := fmt.Sprintf("%s/analysis.json", supportBundleName)
|
||||
|
||||
cmd := exec.Command("../../../bin/support-bundle", "spec/pod.yaml", "--interactive=false", fmt.Sprintf("-o=%s", supportBundleName))
|
||||
cmd := exec.CommandContext(ctx, sbBinary(), "spec/pod.yaml", "--interactive=false", fmt.Sprintf("-o=%s", supportBundleName))
|
||||
cmd.Stdout = &out
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
|
||||
@@ -69,7 +69,7 @@ func TestClusterResources(t *testing.T) {
|
||||
supportBundleName := "cluster-resources"
|
||||
tarPath := fmt.Sprintf("%s.tar.gz", supportBundleName)
|
||||
targetFolder := fmt.Sprintf("%s/cluster-resources/", supportBundleName)
|
||||
cmd := exec.Command("../../../bin/support-bundle", "spec/clusterResources.yaml", "--interactive=false", fmt.Sprintf("-o=%s", supportBundleName))
|
||||
cmd := exec.CommandContext(ctx, sbBinary(), "spec/clusterResources.yaml", "--interactive=false", fmt.Sprintf("-o=%s", supportBundleName))
|
||||
cmd.Stdout = &out
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
|
||||
95
test/e2e/support-bundle/goldpinger_collector_e2e_test.go
Normal file
95
test/e2e/support-bundle/goldpinger_collector_e2e_test.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/replicatedhq/troubleshoot/internal/testutils"
|
||||
"github.com/replicatedhq/troubleshoot/pkg/convert"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"sigs.k8s.io/e2e-framework/pkg/envconf"
|
||||
"sigs.k8s.io/e2e-framework/pkg/features"
|
||||
"sigs.k8s.io/e2e-framework/third_party/helm"
|
||||
)
|
||||
|
||||
var specTemplate = `
|
||||
apiVersion: troubleshoot.sh/v1beta2
|
||||
kind: SupportBundle
|
||||
metadata:
|
||||
name: goldpinger
|
||||
spec:
|
||||
collectors:
|
||||
- goldpinger:
|
||||
namespace: $NAMESPACE
|
||||
analyzers:
|
||||
- goldpinger: {}
|
||||
`
|
||||
|
||||
func Test_GoldpingerCollector(t *testing.T) {
|
||||
releaseName := "goldpinger"
|
||||
|
||||
feature := features.New("Goldpinger collector and analyser").
|
||||
Setup(func(ctx context.Context, t *testing.T, c *envconf.Config) context.Context {
|
||||
cluster := getClusterFromContext(t, ctx, ClusterName)
|
||||
manager := helm.New(cluster.GetKubeconfig())
|
||||
err := manager.RunInstall(
|
||||
helm.WithName(releaseName),
|
||||
helm.WithNamespace(c.Namespace()),
|
||||
helm.WithChart(testutils.TestFixtureFilePath(t, "charts/goldpinger-6.0.1.tgz")),
|
||||
helm.WithWait(),
|
||||
helm.WithTimeout("1m"),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
return ctx
|
||||
}).
|
||||
Assess("collect and analyse goldpinger pings", func(ctx context.Context, t *testing.T, c *envconf.Config) context.Context {
|
||||
var out bytes.Buffer
|
||||
|
||||
namespace := c.Namespace()
|
||||
supportBundleName := "goldpinger-test"
|
||||
spec := strings.ReplaceAll(specTemplate, "$NAMESPACE", namespace)
|
||||
specPath := filepath.Join(t.TempDir(), "goldpinger.yaml")
|
||||
|
||||
err := os.WriteFile(specPath, []byte(spec), 0644)
|
||||
require.NoError(t, err)
|
||||
|
||||
tarPath := filepath.Join(t.TempDir(), fmt.Sprintf("%s.tar.gz", supportBundleName))
|
||||
cmd := exec.CommandContext(ctx, sbBinary(), specPath, "--interactive=false", "-v=2", fmt.Sprintf("-o=%s", tarPath))
|
||||
cmd.Stdout = &out
|
||||
err = cmd.Run()
|
||||
t.Log(out.String())
|
||||
require.NoError(t, err)
|
||||
|
||||
analysisJSON, err := readFileFromTar(tarPath, fmt.Sprintf("%s/analysis.json", supportBundleName))
|
||||
require.NoError(t, err)
|
||||
|
||||
var analysisResults []convert.Result
|
||||
err = json.Unmarshal(analysisJSON, &analysisResults)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Check that we analysed collected goldpinger results.
|
||||
// There won't be any ping results because goldpinger would not have run yet.
|
||||
// The test is fine since this checks that we query the goldpinger results correctly
|
||||
// and the analyser is working.
|
||||
require.Equal(t, 1, len(analysisResults))
|
||||
assert.True(t, strings.HasPrefix(analysisResults[0].Name, "missing.ping.results.for.goldpinger."))
|
||||
assert.Equal(t, convert.SeverityWarn, analysisResults[0].Severity)
|
||||
return ctx
|
||||
}).
|
||||
Teardown(func(ctx context.Context, t *testing.T, c *envconf.Config) context.Context {
|
||||
cluster := getClusterFromContext(t, ctx, ClusterName)
|
||||
manager := helm.New(cluster.GetKubeconfig())
|
||||
manager.RunUninstall(helm.WithName(releaseName), helm.WithNamespace(c.Namespace()))
|
||||
return ctx
|
||||
}).
|
||||
Feature()
|
||||
testenv.Test(t, feature)
|
||||
}
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"sigs.k8s.io/e2e-framework/pkg/envconf"
|
||||
"sigs.k8s.io/e2e-framework/pkg/envfuncs"
|
||||
"sigs.k8s.io/e2e-framework/pkg/features"
|
||||
"sigs.k8s.io/e2e-framework/third_party/helm"
|
||||
|
||||
@@ -26,10 +25,7 @@ func Test_HelmCollector(t *testing.T) {
|
||||
|
||||
feature := features.New("Collector Helm Release").
|
||||
Setup(func(ctx context.Context, t *testing.T, c *envconf.Config) context.Context {
|
||||
cluster, ok := envfuncs.GetKindClusterFromContext(ctx, ClusterName)
|
||||
if !ok {
|
||||
t.Fatalf("Failed to extract kind cluster %s from context", ClusterName)
|
||||
}
|
||||
cluster := getClusterFromContext(t, ctx, ClusterName)
|
||||
manager := helm.New(cluster.GetKubeconfig())
|
||||
manager.RunInstall(helm.WithName(releaseName), helm.WithNamespace(c.Namespace()), helm.WithChart(filepath.Join(curDir, "testdata/charts/nginx-15.2.0.tgz")), helm.WithWait(), helm.WithTimeout("1m"))
|
||||
//ignore error to allow test to speed up, helm collector will catch the pending or deployed helm release status
|
||||
@@ -43,7 +39,7 @@ func Test_HelmCollector(t *testing.T) {
|
||||
namespace := c.Namespace()
|
||||
tarPath := fmt.Sprintf("%s.tar.gz", supportBundleName)
|
||||
targetFile := fmt.Sprintf("%s/helm/%s.json", supportBundleName, namespace)
|
||||
cmd := exec.Command("../../../bin/support-bundle", "spec/helm.yaml", "--interactive=false", fmt.Sprintf("-o=%s", supportBundleName))
|
||||
cmd := exec.CommandContext(ctx, sbBinary(), "spec/helm.yaml", "--interactive=false", fmt.Sprintf("-o=%s", supportBundleName))
|
||||
cmd.Stdout = &out
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
@@ -72,6 +68,12 @@ func Test_HelmCollector(t *testing.T) {
|
||||
assert.Equal(t, "nginx", results[0].Chart)
|
||||
return ctx
|
||||
}).
|
||||
Teardown(func(ctx context.Context, t *testing.T, c *envconf.Config) context.Context {
|
||||
cluster := getClusterFromContext(t, ctx, ClusterName)
|
||||
manager := helm.New(cluster.GetKubeconfig())
|
||||
manager.RunUninstall(helm.WithName(releaseName), helm.WithNamespace(c.Namespace()))
|
||||
return ctx
|
||||
}).
|
||||
Feature()
|
||||
testenv.Test(t, feature)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
@@ -14,6 +15,7 @@ import (
|
||||
"sigs.k8s.io/e2e-framework/pkg/env"
|
||||
"sigs.k8s.io/e2e-framework/pkg/envconf"
|
||||
"sigs.k8s.io/e2e-framework/pkg/envfuncs"
|
||||
"sigs.k8s.io/e2e-framework/support/kind"
|
||||
)
|
||||
|
||||
var testenv env.Environment
|
||||
@@ -24,16 +26,29 @@ func TestMain(m *testing.M) {
|
||||
testenv = env.New()
|
||||
namespace := envconf.RandomName("default", 16)
|
||||
testenv.Setup(
|
||||
envfuncs.CreateKindCluster(ClusterName),
|
||||
envfuncs.CreateCluster(kind.NewProvider(), ClusterName),
|
||||
envfuncs.CreateNamespace(namespace),
|
||||
)
|
||||
testenv.Finish(
|
||||
envfuncs.DeleteNamespace(namespace),
|
||||
envfuncs.DestroyKindCluster(ClusterName),
|
||||
envfuncs.DestroyCluster(ClusterName),
|
||||
)
|
||||
os.Exit(testenv.Run(m))
|
||||
}
|
||||
|
||||
func getClusterFromContext(t *testing.T, ctx context.Context, clusterName string) *kind.Cluster {
|
||||
provider, ok := envfuncs.GetClusterFromContext(ctx, ClusterName)
|
||||
if !ok {
|
||||
t.Fatalf("Failed to extract kind cluster %s from context", ClusterName)
|
||||
}
|
||||
cluster, ok := provider.(*kind.Cluster)
|
||||
if !ok {
|
||||
t.Fatalf("Failed to cast kind cluster %s from provider", ClusterName)
|
||||
}
|
||||
|
||||
return cluster
|
||||
}
|
||||
|
||||
func readFilesAndFoldersFromTar(tarPath, targetFolder string) ([]string, []string, error) {
|
||||
file, err := os.Open(tarPath)
|
||||
if err != nil {
|
||||
@@ -112,5 +127,9 @@ func readFileFromTar(tarPath, targetFile string) ([]byte, error) {
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("File not found: %s", targetFile)
|
||||
return nil, fmt.Errorf("File not found: %q", targetFile)
|
||||
}
|
||||
|
||||
func sbBinary() string {
|
||||
return "../../../bin/support-bundle"
|
||||
}
|
||||
Reference in New Issue
Block a user